Improve handling of disconnects and reconnects (#228)

* Check response 0 on disconnect

From recv(): The return value will be 0 when the peer has performed an orderly shutdown

* Add persistent presence and handlers

* Use buffer instead of raw struct

* Clear presence data on shutdown

* Remove CurrentPresence and add boolean instead

This removes the need for having 2 big buffers in favor of using a small boolean
This commit is contained in:
Florian Spieß 2018-11-16 19:41:49 +01:00 committed by Mason Sciotti
parent 98855b4d84
commit dd47c7c66d
2 changed files with 13 additions and 6 deletions

View file

@ -118,5 +118,8 @@ bool BaseConnection::Read(void* data, size_t length)
} }
Close(); Close();
} }
else if (res == 0) {
Close();
}
return res == (int)length; return res == (int)length;
} }

View file

@ -54,6 +54,7 @@ static std::atomic_bool WasJustDisconnected{false};
static std::atomic_bool GotErrorMessage{false}; static std::atomic_bool GotErrorMessage{false};
static std::atomic_bool WasJoinGame{false}; static std::atomic_bool WasJoinGame{false};
static std::atomic_bool WasSpectateGame{false}; static std::atomic_bool WasSpectateGame{false};
static std::atomic_bool UpdatePresence{false};
static char JoinGameSecret[256]; static char JoinGameSecret[256];
static char SpectateGameSecret[256]; static char SpectateGameSecret[256];
static int LastErrorCode{0}; static int LastErrorCode{0};
@ -214,17 +215,17 @@ static void Discord_UpdateConnection(void)
} }
// writes // writes
if (QueuedPresence.length) { if (UpdatePresence.exchange(false) && QueuedPresence.length) {
QueuedMessage local; QueuedMessage local;
{ {
std::lock_guard<std::mutex> guard(PresenceMutex); std::lock_guard<std::mutex> guard(PresenceMutex);
local.Copy(QueuedPresence); local.Copy(QueuedPresence);
QueuedPresence.length = 0;
} }
if (!Connection->Write(local.buffer, local.length)) { if (!Connection->Write(local.buffer, local.length)) {
// if we fail to send, requeue // if we fail to send, requeue
std::lock_guard<std::mutex> guard(PresenceMutex); std::lock_guard<std::mutex> guard(PresenceMutex);
QueuedPresence.Copy(local); QueuedPresence.Copy(local);
UpdatePresence.exchange(true);
} }
} }
@ -310,6 +311,10 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
Connection = RpcConnection::Create(applicationId); Connection = RpcConnection::Create(applicationId);
Connection->onConnect = [](JsonDocument& readyMessage) { Connection->onConnect = [](JsonDocument& readyMessage) {
Discord_UpdateHandlers(&QueuedHandlers); Discord_UpdateHandlers(&QueuedHandlers);
if (QueuedPresence.length > 0) {
UpdatePresence.exchange(true);
SignalIOActivity();
}
auto data = GetObjMember(&readyMessage, "data"); auto data = GetObjMember(&readyMessage, "data");
auto user = GetObjMember(data, "user"); auto user = GetObjMember(data, "user");
auto userId = GetStrMember(user, "id"); auto userId = GetStrMember(user, "id");
@ -335,10 +340,6 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
Connection->onDisconnect = [](int err, const char* message) { Connection->onDisconnect = [](int err, const char* message) {
LastDisconnectErrorCode = err; LastDisconnectErrorCode = err;
StringCopy(LastDisconnectErrorMessage, message); StringCopy(LastDisconnectErrorMessage, message);
{
std::lock_guard<std::mutex> guard(HandlerMutex);
Handlers = {};
}
WasJustDisconnected.exchange(true); WasJustDisconnected.exchange(true);
UpdateReconnectTime(); UpdateReconnectTime();
}; };
@ -354,6 +355,8 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void)
Connection->onConnect = nullptr; Connection->onConnect = nullptr;
Connection->onDisconnect = nullptr; Connection->onDisconnect = nullptr;
Handlers = {}; Handlers = {};
QueuedPresence.length = 0;
UpdatePresence.exchange(false);
if (IoThread != nullptr) { if (IoThread != nullptr) {
IoThread->Stop(); IoThread->Stop();
delete IoThread; delete IoThread;
@ -369,6 +372,7 @@ extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence*
std::lock_guard<std::mutex> guard(PresenceMutex); std::lock_guard<std::mutex> guard(PresenceMutex);
QueuedPresence.length = JsonWriteRichPresenceObj( QueuedPresence.length = JsonWriteRichPresenceObj(
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
UpdatePresence.exchange(true);
} }
SignalIOActivity(); SignalIOActivity();
} }