From 9f0d204f5690d04ef292b2e4802e754169507277 Mon Sep 17 00:00:00 2001 From: lotodore Date: Tue, 4 Mar 2008 23:47:45 +0000 Subject: [PATCH] First test version with network timeout. Only activity timeout and global timeout, no game admin timeout yet. Set to test values (will disconnect rapidly). Modified method for init timeout (if session cannot be established) - now using one non-modifiable timer for each session, and an additional timer which is reset whenever session data is received. --- src/gui/generic/serverguiwrapper.cpp | 1 + src/gui/generic/serverguiwrapper.h | 1 + src/gui/qt/guiwrapper.cpp | 2 +- src/gui/qt/guiwrapper.h | 2 +- src/gui/qt/mainwindow/mainwindowimpl.cpp | 6 +- src/gui/qt/mainwindow/mainwindowimpl.h | 4 +- .../qt/timeoutmsgbox/timeoutmsgboximpl.cpp | 2 +- src/net/clientcallback.h | 3 +- src/net/clientthread.h | 1 + src/net/common/clientstate.cpp | 6 ++ src/net/common/clientthread.cpp | 8 ++ src/net/common/netpacket.cpp | 2 + src/net/common/servergamestate.cpp | 2 + src/net/common/serverlobbythread.cpp | 85 ++++++++++--------- src/net/common/sessiondata.cpp | 40 ++++++++- src/net/common/sessionmanager.cpp | 20 +++++ src/net/serverlobbythread.h | 6 +- src/net/sessiondata.h | 10 +++ src/net/sessionmanager.h | 1 + src/session.cpp | 7 ++ src/session.h | 2 + 21 files changed, 158 insertions(+), 53 deletions(-) diff --git a/src/gui/generic/serverguiwrapper.cpp b/src/gui/generic/serverguiwrapper.cpp index 29a99ae5..19ae89fa 100644 --- a/src/gui/generic/serverguiwrapper.cpp +++ b/src/gui/generic/serverguiwrapper.cpp @@ -118,6 +118,7 @@ void ServerGuiWrapper::SignalNetClientGameInfo(int actionID) { if (myClientcb) m void ServerGuiWrapper::SignalNetClientError(int errorID, int osErrorID) { if (myClientcb) myClientcb->SignalNetClientError(errorID, osErrorID); } void ServerGuiWrapper::SignalNetClientNotification(int notificationId) { if (myClientcb) myClientcb->SignalNetClientNotification(notificationId); } void ServerGuiWrapper::SignalNetClientStatsUpdate(const ServerStats &stats) { if (myClientcb) myClientcb->SignalNetClientStatsUpdate(stats); } +void ServerGuiWrapper::SignalNetClientShowTimeoutDialog(NetTimeoutReason reason, unsigned remainingSec) { if (myClientcb) myClientcb->SignalNetClientShowTimeoutDialog(reason, remainingSec); } void ServerGuiWrapper::SignalNetClientRemovedFromGame(int notificationId) { if (myClientcb) myClientcb->SignalNetClientRemovedFromGame(notificationId); } void ServerGuiWrapper::SignalNetClientSelfJoined(unsigned playerId, const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientSelfJoined(playerId, playerName, rights); } void ServerGuiWrapper::SignalNetClientPlayerJoined(unsigned playerId, const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerId, playerName, rights); } diff --git a/src/gui/generic/serverguiwrapper.h b/src/gui/generic/serverguiwrapper.h index 347b5ceb..d6c47b2c 100644 --- a/src/gui/generic/serverguiwrapper.h +++ b/src/gui/generic/serverguiwrapper.h @@ -101,6 +101,7 @@ public: void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientNotification(int notificationId); void SignalNetClientStatsUpdate(const ServerStats &stats); + void SignalNetClientShowTimeoutDialog(NetTimeoutReason reason, unsigned remainingSec); void SignalNetClientRemovedFromGame(int notificationId); void SignalNetClientSelfJoined(unsigned playerId, const std::string &playerName, PlayerRights rights); void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights); diff --git a/src/gui/qt/guiwrapper.cpp b/src/gui/qt/guiwrapper.cpp index 6e426431..736b5e52 100644 --- a/src/gui/qt/guiwrapper.cpp +++ b/src/gui/qt/guiwrapper.cpp @@ -120,7 +120,7 @@ void GuiWrapper::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGam void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); } void GuiWrapper::SignalNetClientNotification(int notificationId) { myW->signalNetClientNotification(notificationId); } void GuiWrapper::SignalNetClientStatsUpdate(const ServerStats &stats) { myW->signalNetClientStatsUpdate(stats); } -void GuiWrapper::SignalNetClientShowTimeoutDialog(int msgID, int duration) { myW->signalNetClientShowTimeoutDialog(msgID, duration); } +void GuiWrapper::SignalNetClientShowTimeoutDialog(NetTimeoutReason reason, unsigned remainingSec) { myW->signalNetClientShowTimeoutDialog(reason, remainingSec); } void GuiWrapper::SignalNetClientRemovedFromGame(int notificationId) { myW->signalNetClientRemovedFromGame(notificationId); } void GuiWrapper::SignalNetClientSelfJoined(unsigned playerId, const string &playerName, PlayerRights rights) { myW->signalNetClientSelfJoined(playerId, QString::fromUtf8(playerName.c_str()), rights); } void GuiWrapper::SignalNetClientPlayerJoined(unsigned playerId, const string &playerName, PlayerRights rights) { myW->signalNetClientPlayerJoined(playerId, QString::fromUtf8(playerName.c_str()), rights); } diff --git a/src/gui/qt/guiwrapper.h b/src/gui/qt/guiwrapper.h index 74e57ca3..91706719 100644 --- a/src/gui/qt/guiwrapper.h +++ b/src/gui/qt/guiwrapper.h @@ -108,7 +108,7 @@ public: void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientNotification(int notificationId); void SignalNetClientStatsUpdate(const ServerStats &stats); - void SignalNetClientShowTimeoutDialog(int, int); + void SignalNetClientShowTimeoutDialog(NetTimeoutReason reason, unsigned remainingSec); void SignalNetClientRemovedFromGame(int notificationId); void SignalNetClientSelfJoined(unsigned playerId, const std::string &playerName, PlayerRights rights); void SignalNetClientPlayerJoined(unsigned playerId, const std::string &playerName, PlayerRights rights); diff --git a/src/gui/qt/mainwindow/mainwindowimpl.cpp b/src/gui/qt/mainwindow/mainwindowimpl.cpp index ee0d90ec..4a3b3b67 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.cpp +++ b/src/gui/qt/mainwindow/mainwindowimpl.cpp @@ -639,7 +639,7 @@ mainWindowImpl::mainWindowImpl(ConfigFile *c, QMainWindow *parent) connect(this, SIGNAL(signalNetClientGameListPlayerLeft(unsigned, unsigned)), myGameLobbyDialog, SLOT(gameRemovePlayer(unsigned, unsigned))); connect(this, SIGNAL(signalNetClientRemovedFromGame(int)), myGameLobbyDialog, SLOT(removedFromGame(int))); connect(this, SIGNAL(signalNetClientStatsUpdate(ServerStats)), myGameLobbyDialog, SLOT(updateStats(ServerStats))); - connect(this, SIGNAL(signalNetClientShowTimeoutDialog(int, int)), this, SLOT(showTimeoutDialog(int, int))); + connect(this, SIGNAL(signalNetClientShowTimeoutDialog(int, unsigned)), this, SLOT(showTimeoutDialog(int, unsigned))); // Errors are handled globally, not within one dialog. connect(this, SIGNAL(signalNetClientError(int, int)), this, SLOT(networkError(int, int))); @@ -3777,10 +3777,10 @@ void mainWindowImpl::leaveCurrentNetworkGame() { } -void mainWindowImpl::showTimeoutDialog(int msgID, int duration) { +void mainWindowImpl::showTimeoutDialog(int msgID, unsigned duration) { myTimeoutDialog->setMySession(mySession); - myTimeoutDialog->setMsgID(msgID); + myTimeoutDialog->setMsgID((NetTimeoutReason)msgID); myTimeoutDialog->setTimeoutDuration(duration); myTimeoutDialog->show(); myTimeoutDialog->raise(); diff --git a/src/gui/qt/mainwindow/mainwindowimpl.h b/src/gui/qt/mainwindow/mainwindowimpl.h index e9e668df..70dcb489 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.h +++ b/src/gui/qt/mainwindow/mainwindowimpl.h @@ -132,7 +132,7 @@ signals: void signalNetClientError(int errorID, int osErrorID); void signalNetClientNotification(int notificationId); void signalNetClientStatsUpdate(ServerStats stats); - void signalNetClientShowTimeoutDialog(int, int); + void signalNetClientShowTimeoutDialog(int, unsigned); void signalNetClientRemovedFromGame(int notificationId); void signalNetServerError(int errorID, int osErrorID); void signalNetClientSelfJoined(unsigned playerId, QString playerName, int rights); @@ -334,7 +334,7 @@ public slots: void showMaximized (); void quitPokerTH(); - void showTimeoutDialog(int msgID, int duration); + void showTimeoutDialog(int msgID, unsigned duration); void hideTimeoutDialog(); // void paintEvent(QPaintEvent *); diff --git a/src/gui/qt/timeoutmsgbox/timeoutmsgboximpl.cpp b/src/gui/qt/timeoutmsgbox/timeoutmsgboximpl.cpp index f7d03416..d24eb81e 100644 --- a/src/gui/qt/timeoutmsgbox/timeoutmsgboximpl.cpp +++ b/src/gui/qt/timeoutmsgbox/timeoutmsgboximpl.cpp @@ -59,5 +59,5 @@ void timeoutMsgBoxImpl::timerRefresh() { void timeoutMsgBoxImpl::stopTimeout() { -// mySession->stopTimeout + mySession->resetNetworkTimeout(); } diff --git a/src/net/clientcallback.h b/src/net/clientcallback.h index 7955c4e9..6e7a770f 100644 --- a/src/net/clientcallback.h +++ b/src/net/clientcallback.h @@ -39,6 +39,7 @@ public: virtual void SignalNetClientError(int errorID, int osErrorID) = 0; virtual void SignalNetClientNotification(int notificationId) = 0; virtual void SignalNetClientStatsUpdate(const ServerStats &stats) = 0; + virtual void SignalNetClientShowTimeoutDialog(NetTimeoutReason reason, unsigned remainingSec) = 0; virtual void SignalNetClientRemovedFromGame(int notificationId) = 0; virtual void SignalNetClientGameListNew(unsigned gameId) = 0; @@ -57,6 +58,6 @@ public: virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0; virtual void SignalNetClientWaitDialog() = 0; -}; + }; #endif diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 276d7298..69b3c485 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -65,6 +65,7 @@ public: void SendJoinFirstGame(const std::string &password); void SendJoinGame(unsigned gameId, const std::string &password); void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password); + void SendResetTimeout(); GameInfo GetGameInfo(unsigned gameId) const; PlayerInfo GetPlayerInfo(unsigned playerId) const; diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 6e4735b8..d4f80fc6 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -417,6 +417,12 @@ AbstractClientStateReceiving::Process(ClientThread &client) client.GetCallback().SignalNetClientRemovedFromGame(removedData.removeReason); client.SetState(ClientStateWaitJoin::Instance()); } + else if (tmpPacket->ToNetPacketTimeoutWarning()) + { + NetPacketTimeoutWarning::Data warningData; + tmpPacket->ToNetPacketTimeoutWarning()->GetData(warningData); + client.GetCallback().SignalNetClientShowTimeoutDialog(warningData.timeoutReason, warningData.remainingSeconds); + } else if (tmpPacket->ToNetPacketChatText()) { // Chat message - display it in the GUI. diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index c1f47fca..3c63d38a 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -241,6 +241,14 @@ ClientThread::SendCreateGame(const GameData &gameData, const std::string &name, } } +void +ClientThread::SendResetTimeout() +{ + boost::shared_ptr reset(new NetPacketResetTimeout); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(reset); +} + GameInfo ClientThread::GetGameInfo(unsigned gameId) const { diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 99af0eab..0e5487cc 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -4354,6 +4354,7 @@ NetPacketTimeoutWarning::SetData(const NetPacketTimeoutWarning::Data &inData) tmpData->timeoutReason = htons(NET_TIMEOUT_OTHER_REASON); break; } + tmpData->remainingSeconds = htons(inData.remainingSeconds); // Check the packet - just in case. Check(GetRawData()); @@ -4374,6 +4375,7 @@ NetPacketTimeoutWarning::GetData(NetPacketTimeoutWarning::Data &outData) const outData.timeoutReason = NETWORK_TIMEOUT_GENERIC; break; } + outData.remainingSeconds = ntohs(tmpData->remainingSeconds); } const NetPacketTimeoutWarning * diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 1fe649a6..89571561 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -175,6 +175,8 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server) // Delegate to Lobby. server.GetLobbyThread().HandleGameRetrieveAvatar(session, *packet->ToNetPacketRetrieveAvatar()); } + else if (packet->ToNetPacketResetTimeout()) + {} else if (packet->ToNetPacketLeaveCurrentGame()) { server.MoveSessionToLobby(session, NTF_NET_REMOVED_ON_REQUEST); diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 42c855d8..dd5009f9 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -34,11 +34,15 @@ #include #include -#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby. -#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day -#define SERVER_SAVE_STATISTICS_INTERVAL_SEC 60 -#define SERVER_INIT_SESSION_TIMEOUT_SEC 20 -#define SERVER_INIT_AVATAR_CLIENT_LOCK_SEC 30 // Forbid a client to send an additional avatar. +#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby. +#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day +#define SERVER_SAVE_STATISTICS_INTERVAL_SEC 60 +#define SERVER_INIT_AVATAR_CLIENT_LOCK_SEC 30 // Forbid a client to send an additional avatar. + +#define SERVER_INIT_SESSION_TIMEOUT_SEC 20 +#define SERVER_TIMEOUT_WARNING_REMAINING_SEC 60 +#define SERVER_SESSION_ACTIVITY_TIMEOUT_SEC 90 // MUST be > SERVER_TIMEOUT_WARNING_REMAINING_SEC +#define SERVER_SESSION_FORCED_TIMEOUT_SEC 300 // Should be quite large. #define SERVER_STATISTICS_FILE_NAME "server_statistics.log" #define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn" @@ -142,10 +146,6 @@ ServerLobbyThread::RemoveSessionFromGame(SessionWrapper session) void ServerLobbyThread::CloseSession(SessionWrapper session) { - { - boost::mutex::scoped_lock lock(m_initTimerSessionMapMutex); - m_initTimerSessionMap.erase(session.sessionData->GetId()); - } m_sessionManager.RemoveSession(session.sessionData->GetId()); m_gameSessionManager.RemoveSession(session.sessionData->GetId()); @@ -308,12 +308,13 @@ ServerLobbyThread::Main() NewSessionLoop(); // Main loop. ProcessLoop(); - // Close sessions. - CloseSessionLoop(); // Remove games. RemoveGameLoop(); // Kick players. KickPlayerLoop(); + // Check session timeouts. + m_sessionManager.ForEachRemoveIf(boost::bind(&ServerLobbyThread::CheckSessionTimeouts, boost::ref(*this), _1)); + m_gameSessionManager.ForEachRemoveIf(boost::bind(&ServerLobbyThread::CheckSessionTimeouts, boost::ref(*this), _1)); // Update avatar limitation lock. UpdateAvatarClientTimerLoop(); // Cleanup cache. @@ -383,6 +384,8 @@ ServerLobbyThread::ProcessLoop() HandleNetPacketRetrievePlayerInfo(session, *packet->ToNetPacketRetrievePlayerInfo()); else if (packet->ToNetPacketRetrieveAvatar()) HandleNetPacketRetrieveAvatar(session, *packet->ToNetPacketRetrieveAvatar()); + else if (packet->ToNetPacketResetTimeout()) + {} else if (packet->ToNetPacketCreateGame()) HandleNetPacketCreateGame(session, *packet->ToNetPacketCreateGame()); else if (packet->ToNetPacketJoinGame()) @@ -697,10 +700,6 @@ ServerLobbyThread::EstablishSession(SessionWrapper session) SendGameList(session.sessionData); // Session is now established. - { - boost::mutex::scoped_lock lock(m_initTimerSessionMapMutex); - m_initTimerSessionMap.erase(session.sessionData->GetId()); - } session.sessionData->SetState(SessionData::Established); { @@ -764,27 +763,6 @@ ServerLobbyThread::NewSessionLoop() HandleReAddedSession(tmpSession); } -void -ServerLobbyThread::CloseSessionLoop() -{ - boost::mutex::scoped_lock lock(m_initTimerSessionMapMutex); - TimerSessionMap::iterator i = m_initTimerSessionMap.begin(); - TimerSessionMap::iterator end = m_initTimerSessionMap.end(); - - // Remove sessions if they do not initialize within a certain period. - while (i != end) - { - TimerSessionMap::iterator next = i; - ++next; - if (i->second.elapsed().total_seconds() > SERVER_INIT_SESSION_TIMEOUT_SEC) - { - m_sessionManager.RemoveSession(i->first); - m_initTimerSessionMap.erase(i); - } - i = next; - } -} - void ServerLobbyThread::RemoveGameLoop() { @@ -956,8 +934,6 @@ ServerLobbyThread::HandleNewConnection(boost::shared_ptr connData) tmpAddress[sizeof(tmpAddress) - 1] = 0; // paranoia sessionData->SetClientAddr(tmpAddress); } - boost::mutex::scoped_lock lock(m_initTimerSessionMapMutex); - m_initTimerSessionMap[sessionData->GetId()] = boost::timers::portable::microsec_timer(); } else { @@ -987,6 +963,39 @@ ServerLobbyThread::HandleReAddedSession(SessionWrapper session) } } +bool +ServerLobbyThread::CheckSessionTimeouts(SessionWrapper session) +{ + bool retVal = false; + if (session.sessionData.get()) + { + if (session.sessionData->GetState() == SessionData::Init && session.sessionData->GetAutoDisconnectTimerElapsedSec() >= SERVER_INIT_SESSION_TIMEOUT_SEC) + retVal = true; + else if (session.sessionData->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC - SERVER_TIMEOUT_WARNING_REMAINING_SEC + && !session.sessionData->HasActivityNoticeBeenSent()) + { + session.sessionData->MarkActivityNotice(); + boost::shared_ptr packet(new NetPacketTimeoutWarning); + NetPacketTimeoutWarning::Data warningData; + warningData.timeoutReason = NETWORK_TIMEOUT_GENERIC; + warningData.remainingSeconds = SERVER_TIMEOUT_WARNING_REMAINING_SEC; + static_cast(packet.get())->SetData(warningData); + GetSender().Send(session.sessionData, packet); + } + else if (session.sessionData->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC) + { + // TODO SendError(session.sessionData, errorCode); + retVal = true; + } + else if (session.sessionData->GetAutoDisconnectTimerElapsedSec() >= SERVER_SESSION_FORCED_TIMEOUT_SEC) + { + // TODO SendError(session.sessionData, errorCode); + retVal = true; + } + } + return retVal; +} + void ServerLobbyThread::CleanupConnectQueue() { diff --git a/src/net/common/sessiondata.cpp b/src/net/common/sessiondata.cpp index cd82e060..a0621c38 100644 --- a/src/net/common/sessiondata.cpp +++ b/src/net/common/sessiondata.cpp @@ -20,7 +20,8 @@ #include SessionData::SessionData(SOCKET sockfd, SessionId id) -: m_sockfd(sockfd), m_id(id), m_state(SessionData::Init), m_readyFlag(false) +: m_sockfd(sockfd), m_id(id), m_state(SessionData::Init), m_readyFlag(false), + m_activityTimeoutNoticeSent(false) { } @@ -100,3 +101,40 @@ SessionData::GetReceiveBuffer() return m_receiveBuffer; } +void +SessionData::ResetActivityTimer() +{ + boost::mutex::scoped_lock lock(m_dataMutex); + m_activityTimeoutNoticeSent = false; + m_activityTimer.reset(); + m_activityTimer.start(); +} + +unsigned +SessionData::GetActivityTimerElapsedSec() const +{ + boost::mutex::scoped_lock lock(m_dataMutex); + return m_activityTimer.elapsed().total_seconds(); +} + +bool +SessionData::HasActivityNoticeBeenSent() const +{ + boost::mutex::scoped_lock lock(m_dataMutex); + return m_activityTimeoutNoticeSent; +} + +void +SessionData::MarkActivityNotice() +{ + boost::mutex::scoped_lock lock(m_dataMutex); + m_activityTimeoutNoticeSent = true; +} + +unsigned +SessionData::GetAutoDisconnectTimerElapsedSec() const +{ + boost::mutex::scoped_lock lock(m_dataMutex); + return m_autoDisconnectTimer.elapsed().total_seconds(); +} + diff --git a/src/net/common/sessionmanager.cpp b/src/net/common/sessionmanager.cpp index bb507470..a7a61bb8 100644 --- a/src/net/common/sessionmanager.cpp +++ b/src/net/common/sessionmanager.cpp @@ -147,6 +147,8 @@ SessionManager::Select(unsigned timeoutMsec) } } } + if (retSession.sessionData.get()) + retSession.sessionData->ResetActivityTimer(); return retSession; } @@ -294,6 +296,24 @@ SessionManager::ForEach(boost::function func) } } +void +SessionManager::ForEachRemoveIf(boost::function func) +{ + boost::mutex::scoped_lock lock(m_sessionMapMutex); + + SessionMap::iterator i = m_sessionMap.begin(); + SessionMap::iterator end = m_sessionMap.end(); + + while (i != end) + { + SessionMap::iterator next = i; + next++; + if (func((*i).second)) + m_sessionMap.erase(i); + i = next; + } +} + unsigned SessionManager::CountReadySessions() const { diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 5f289199..51c867d4 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -113,7 +113,6 @@ protected: void RequestPlayerAvatar(SessionWrapper session); void NewConnectionLoop(); void NewSessionLoop(); - void CloseSessionLoop(); void RemoveGameLoop(); void KickPlayerLoop(); void UpdateAvatarClientTimerLoop(); @@ -128,7 +127,7 @@ protected: void HandleNewConnection(boost::shared_ptr connData); void HandleReAddedSession(SessionWrapper session); - SOCKET Select(); + bool CheckSessionTimeouts(SessionWrapper session); void CleanupConnectQueue(); void CleanupSessionMap(); @@ -166,9 +165,6 @@ private: SessionManager m_sessionManager; SessionManager m_gameSessionManager; - TimerSessionMap m_initTimerSessionMap; - mutable boost::mutex m_initTimerSessionMapMutex; - TimerClientAddressMap m_timerAvatarClientAddressMap; mutable boost::mutex m_timerAvatarClientAddressMapMutex; diff --git a/src/net/sessiondata.h b/src/net/sessiondata.h index a99a3160..0b0a708b 100644 --- a/src/net/sessiondata.h +++ b/src/net/sessiondata.h @@ -25,6 +25,7 @@ #include #include #include +#include #define INVALID_SESSION 0 #define SESSION_ID_INIT INVALID_SESSION @@ -60,6 +61,12 @@ public: ReceiveBuffer &GetReceiveBuffer(); + void ResetActivityTimer(); + unsigned GetActivityTimerElapsedSec() const; + bool HasActivityNoticeBeenSent() const; + void MarkActivityNotice(); + unsigned GetAutoDisconnectTimerElapsedSec() const; + private: SOCKET m_sockfd; const SessionId m_id; @@ -67,6 +74,9 @@ private: std::string m_clientAddr; ReceiveBuffer m_receiveBuffer; bool m_readyFlag; + boost::timers::portable::microsec_timer m_activityTimer; + bool m_activityTimeoutNoticeSent; + boost::timers::portable::microsec_timer m_autoDisconnectTimer; mutable boost::mutex m_dataMutex; }; diff --git a/src/net/sessionmanager.h b/src/net/sessionmanager.h index 4b5983c5..24db2461 100644 --- a/src/net/sessionmanager.h +++ b/src/net/sessionmanager.h @@ -66,6 +66,7 @@ public: bool IsPlayerConnected(unsigned uniqueId) const; void ForEach(boost::function func); + void ForEachRemoveIf(boost::function func); unsigned CountReadySessions() const; void ResetAllReadyFlags(); diff --git a/src/session.cpp b/src/session.cpp index 85c7960a..137ba407 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -368,6 +368,13 @@ void Session::kickPlayer(unsigned playerId) myNetClient->SendKickPlayer(playerId); } +void Session::resetNetworkTimeout() +{ + if (!myNetClient) + return; // only act if client is running. + myNetClient->SendResetTimeout(); +} + void Session::kickPlayer(const string &playerName) { if (!myNetClient) diff --git a/src/session.h b/src/session.h index be0f0ec5..f8924662 100755 --- a/src/session.h +++ b/src/session.h @@ -80,6 +80,8 @@ public: void sendChatMessage(const std::string &message); void kickPlayer(unsigned playerId); void kickPlayer(const std::string &playerName); + + void resetNetworkTimeout(); bool isNetworkClientRunning() const; // TODO hack bool isNetworkServerRunning() const; // TODO hack