#pragma once #include #include "RWLock.h" #include "SocketMgr.h" #include "KOSocket.h" typedef std::map SessionMap; template class KOSocketMgr : public SocketMgr { public: KOSocketMgr() : m_server(nullptr) {} virtual void InitSessions(uint16 sTotalSessions); virtual bool Listen(uint16 sPort, uint16 sTotalSessions); virtual bool Listen(std::string sIPAddress, uint16 sPort, uint16 sTotalSessions); virtual void OnConnect(Socket *pSock); virtual Socket *AssignSocket(SOCKET socket); virtual void DisconnectCallback(Socket *pSock); void RunServer() { SpawnWorkerThreads(); GetServer()->run(); } // Send a packet to all active sessions void SendAll(Packet * pkt) { std::lock_guard lock(m_lock); SessionMap & sessizmap = m_activeSessions; for (auto itr = sessizmap.begin(); itr != sessizmap.end(); ++itr) itr->second->Send(pkt); } void SendAllCompressed(Packet * result) { std::lock_guard lock(m_lock); SessionMap & sessMap = m_activeSessions; for (auto itr = sessMap.begin(); itr != sessMap.end(); ++itr) itr->second->SendCompressed(result); } ListenSocket * GetServer() { return m_server; } INLINE SessionMap & GetIdleSessionMap() { return m_idleSessions; } INLINE SessionMap & GetActiveSessionMap() { return m_activeSessions; } INLINE std::recursive_mutex& GetLock() { return m_lock; } T * operator[] (uint16 id) { std::lock_guard lock(m_lock); auto itr = m_activeSessions.find(id); if (itr != m_activeSessions.end()) return static_cast(itr->second); return nullptr; } void Shutdown(); virtual ~KOSocketMgr(); protected: SessionMap m_idleSessions, m_activeSessions; std::recursive_mutex m_lock; private: ListenSocket * m_server; }; template void KOSocketMgr::InitSessions(uint16 sTotalSessions) { std::lock_guard lock(m_lock); for (uint16 i = 0; i < sTotalSessions; i++) m_idleSessions.insert(std::make_pair(i, new T(i, this))); } template bool KOSocketMgr::Listen(uint16 sPort, uint16 sTotalSessions) { return Listen("0.0.0.0", sPort, sTotalSessions); } template bool KOSocketMgr::Listen(std::string sIPAddress, uint16 sPort, uint16 sTotalSessions) { if (m_server != nullptr) return false; CreateCompletionPort(); m_server = new ListenSocket(this, sIPAddress.c_str(), sPort); if (!m_server->IsOpen()) return false; InitSessions(sTotalSessions); return true; } template Socket * KOSocketMgr::AssignSocket(SOCKET socket) { std::lock_guard lock(m_lock); Socket *pSock = nullptr; for (auto itr = m_idleSessions.begin(); itr != m_idleSessions.end(); itr++) { m_activeSessions.insert(std::make_pair(itr->first, itr->second)); pSock = itr->second; m_idleSessions.erase(itr); pSock->SetFd(socket); break; } return pSock; } template void KOSocketMgr::OnConnect(Socket *pSock) { std::lock_guard lock(m_lock); auto itr = m_idleSessions.find(static_cast(pSock)->GetSocketID()); if (itr != m_idleSessions.end()) { m_activeSessions.insert(std::make_pair(itr->first, itr->second)); m_idleSessions.erase(itr); } } template void KOSocketMgr::DisconnectCallback(Socket *pSock) { std::lock_guard lock(m_lock); auto itr = m_activeSessions.find(static_cast(pSock)->GetSocketID()); if (itr != m_activeSessions.end()) { m_idleSessions.insert(std::make_pair(itr->first, itr->second)); m_activeSessions.erase(itr); } } template void KOSocketMgr::Shutdown() { if (m_bShutdown) return; if (m_server != nullptr) delete m_server; SocketMgr::Shutdown(); } template KOSocketMgr::~KOSocketMgr() { Shutdown(); }