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_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby.
#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day
#define SERVER_INIT_SESSION_TIMEOUT_SEC 20
#define SERVER_COMPUTER_PLAYER_NAME "Computer"
@@ -122,6 +123,7 @@ ServerLobbyThread::RemoveSessionFromGame(SessionWrapper session)
void
ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
{
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
m_sessionManager.RemoveSession(session.sessionData->GetSocket());
m_gameSessionManager.RemoveSession(session.sessionData->GetSocket());
@@ -253,35 +255,11 @@ ServerLobbyThread::Main()
{
while (!ShouldTerminate())
{
{
// 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);
}
{
// 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.
// Process new connections.
NewConnectionLoop();
// Process re-added sessions.
NewSessionLoop();
// Main loop.
ProcessLoop();
// Close sessions.
CloseSessionLoop();
@@ -320,6 +298,7 @@ ServerLobbyThread::ProcessLoop()
} catch (const NetException &)
{
// On error: Close this session.
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
m_sessionManager.RemoveSession(session.sessionData->GetSocket());
// Update stats (if needed).
BroadcastStatisticsUpdate();
@@ -647,6 +626,7 @@ ServerLobbyThread::EstablishSession(SessionWrapper session)
SendGameList(session.sessionData->GetSocket());
// Session is now established.
m_initTimerSessionMap.erase(session.sessionData->GetSocket());
session.sessionData->SetState(SessionData::Established);
++m_totalPlayersLoggedIn;
@@ -667,20 +647,73 @@ ServerLobbyThread::RequestPlayerAvatar(SessionWrapper session)
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
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)
m_closeSessionList.erase(cur);
// Remove sessions if they do not initialize within a certain period.
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.
boost::shared_ptr<SessionData> sessionData(new SessionData(connData->ReleaseSocket(), sessionId));
m_sessionManager.AddSession(sessionData);
m_initTimerSessionMap[sessionData->GetSocket()] = boost::timers::portable::microsec_timer();
}
else
{
+5
View File
@@ -82,6 +82,7 @@ protected:
typedef std::deque<SessionWrapper> SessionQueue;
typedef std::list<SessionWrapper> SessionList;
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::list<unsigned> RemoveGameList;
@@ -100,6 +101,8 @@ protected:
void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket);
void EstablishSession(SessionWrapper session);
void RequestPlayerAvatar(SessionWrapper session);
void NewConnectionLoop();
void NewSessionLoop();
void CloseSessionLoop();
void RemoveGameLoop();
void CleanupAvatarCache();
@@ -147,6 +150,8 @@ private:
SessionManager m_sessionManager;
SessionManager m_gameSessionManager;
InitTimerSessionMap m_initTimerSessionMap;
CloseSessionList m_closeSessionList;
mutable boost::mutex m_closeSessionListMutex;