If a client does not initialize properly within a certain time, remove the network session.

This commit is contained in:
lotodore
2007-10-26 14:54:57 +00:00
parent 9368c5f16e
commit ae33299758
2 changed files with 77 additions and 38 deletions
+72 -38
View File
@@ -33,6 +33,7 @@
#define SERVER_CLOSE_SESSION_DELAY_SEC 1 #define SERVER_CLOSE_SESSION_DELAY_SEC 1
#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby. #define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby.
#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day #define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day
#define SERVER_INIT_SESSION_TIMEOUT_SEC 20
#define SERVER_COMPUTER_PLAYER_NAME "Computer" #define SERVER_COMPUTER_PLAYER_NAME "Computer"
@@ -122,6 +123,7 @@ ServerLobbyThread::RemoveSessionFromGame(SessionWrapper session)
void void
ServerLobbyThread::CloseSessionDelayed(SessionWrapper session) ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
{ {
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
m_sessionManager.RemoveSession(session.sessionData->GetSocket()); m_sessionManager.RemoveSession(session.sessionData->GetSocket());
m_gameSessionManager.RemoveSession(session.sessionData->GetSocket()); m_gameSessionManager.RemoveSession(session.sessionData->GetSocket());
@@ -253,35 +255,11 @@ ServerLobbyThread::Main()
{ {
while (!ShouldTerminate()) while (!ShouldTerminate())
{ {
{ // Process new connections.
// Handle one incoming connection at a time. NewConnectionLoop();
boost::shared_ptr<ConnectData> tmpData; // Process re-added sessions.
{ NewSessionLoop();
boost::mutex::scoped_lock lock(m_connectQueueMutex); // Main loop.
if (!m_connectQueue.empty())
{
tmpData = m_connectQueue.front();
m_connectQueue.pop_front();
}
}
if (tmpData.get())
HandleNewConnection(tmpData);
}
{
// Handle one incoming session at a time.
SessionWrapper tmpSession;
{
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
if (!m_sessionQueue.empty())
{
tmpSession = m_sessionQueue.front();
m_sessionQueue.pop_front();
}
}
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
HandleReAddedSession(tmpSession);
}
// Process loop.
ProcessLoop(); ProcessLoop();
// Close sessions. // Close sessions.
CloseSessionLoop(); CloseSessionLoop();
@@ -320,6 +298,7 @@ ServerLobbyThread::ProcessLoop()
} catch (const NetException &) } catch (const NetException &)
{ {
// On error: Close this session. // On error: Close this session.
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
m_sessionManager.RemoveSession(session.sessionData->GetSocket()); m_sessionManager.RemoveSession(session.sessionData->GetSocket());
// Update stats (if needed). // Update stats (if needed).
BroadcastStatisticsUpdate(); BroadcastStatisticsUpdate();
@@ -647,6 +626,7 @@ ServerLobbyThread::EstablishSession(SessionWrapper session)
SendGameList(session.sessionData->GetSocket()); SendGameList(session.sessionData->GetSocket());
// Session is now established. // Session is now established.
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
session.sessionData->SetState(SessionData::Established); session.sessionData->SetState(SessionData::Established);
++m_totalPlayersLoggedIn; ++m_totalPlayersLoggedIn;
@@ -667,20 +647,73 @@ ServerLobbyThread::RequestPlayerAvatar(SessionWrapper session)
GetSender().Send(session.sessionData->GetSocket(), retrieveAvatar); GetSender().Send(session.sessionData->GetSocket(), retrieveAvatar);
} }
void
ServerLobbyThread::NewConnectionLoop()
{
// Handle one incoming connection at a time.
boost::shared_ptr<ConnectData> tmpData;
{
boost::mutex::scoped_lock lock(m_connectQueueMutex);
if (!m_connectQueue.empty())
{
tmpData = m_connectQueue.front();
m_connectQueue.pop_front();
}
}
if (tmpData.get())
HandleNewConnection(tmpData);
}
void
ServerLobbyThread::NewSessionLoop()
{
// Handle one incoming session at a time.
SessionWrapper tmpSession;
{
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
if (!m_sessionQueue.empty())
{
tmpSession = m_sessionQueue.front();
m_sessionQueue.pop_front();
}
}
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
HandleReAddedSession(tmpSession);
}
void void
ServerLobbyThread::CloseSessionLoop() ServerLobbyThread::CloseSessionLoop()
{ {
boost::mutex::scoped_lock lock(m_closeSessionListMutex);
CloseSessionList::iterator i = m_closeSessionList.begin();
CloseSessionList::iterator end = m_closeSessionList.end();
while (i != end)
{ {
CloseSessionList::iterator cur = i++; InitTimerSessionMap::iterator i = m_initTimerSessionMap.begin();
InitTimerSessionMap::iterator end = m_initTimerSessionMap.end();
if (cur->first.elapsed().total_seconds() >= SERVER_CLOSE_SESSION_DELAY_SEC) // Remove sessions if they do not initialize within a certain period.
m_closeSessionList.erase(cur); while (i != end)
{
InitTimerSessionMap::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;
}
}
{
boost::mutex::scoped_lock lock(m_closeSessionListMutex);
CloseSessionList::iterator i = m_closeSessionList.begin();
CloseSessionList::iterator end = m_closeSessionList.end();
while (i != end)
{
CloseSessionList::iterator cur = i++;
if (cur->first.elapsed().total_seconds() >= SERVER_CLOSE_SESSION_DELAY_SEC)
m_closeSessionList.erase(cur);
}
} }
} }
@@ -780,6 +813,7 @@ ServerLobbyThread::HandleNewConnection(boost::shared_ptr<ConnectData> connData)
// Create a new session. // Create a new session.
boost::shared_ptr<SessionData> sessionData(new SessionData(connData->ReleaseSocket(), sessionId)); boost::shared_ptr<SessionData> sessionData(new SessionData(connData->ReleaseSocket(), sessionId));
m_sessionManager.AddSession(sessionData); m_sessionManager.AddSession(sessionData);
m_initTimerSessionMap[sessionData->GetSocket()] = boost::timers::portable::microsec_timer();
} }
else else
{ {
+5
View File
@@ -82,6 +82,7 @@ protected:
typedef std::deque<SessionWrapper> SessionQueue; typedef std::deque<SessionWrapper> SessionQueue;
typedef std::list<SessionWrapper> SessionList; typedef std::list<SessionWrapper> SessionList;
typedef std::list<std::pair<boost::timers::portable::microsec_timer, boost::shared_ptr<SessionData> > > CloseSessionList; typedef std::list<std::pair<boost::timers::portable::microsec_timer, boost::shared_ptr<SessionData> > > CloseSessionList;
typedef std::map<SOCKET, boost::timers::portable::microsec_timer> InitTimerSessionMap;
typedef std::map<unsigned, boost::shared_ptr<ServerGameThread> > GameMap; typedef std::map<unsigned, boost::shared_ptr<ServerGameThread> > GameMap;
typedef std::list<unsigned> RemoveGameList; typedef std::list<unsigned> RemoveGameList;
@@ -100,6 +101,8 @@ protected:
void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket); void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket);
void EstablishSession(SessionWrapper session); void EstablishSession(SessionWrapper session);
void RequestPlayerAvatar(SessionWrapper session); void RequestPlayerAvatar(SessionWrapper session);
void NewConnectionLoop();
void NewSessionLoop();
void CloseSessionLoop(); void CloseSessionLoop();
void RemoveGameLoop(); void RemoveGameLoop();
void CleanupAvatarCache(); void CleanupAvatarCache();
@@ -147,6 +150,8 @@ private:
SessionManager m_sessionManager; SessionManager m_sessionManager;
SessionManager m_gameSessionManager; SessionManager m_gameSessionManager;
InitTimerSessionMap m_initTimerSessionMap;
CloseSessionList m_closeSessionList; CloseSessionList m_closeSessionList;
mutable boost::mutex m_closeSessionListMutex; mutable boost::mutex m_closeSessionListMutex;