📄 warsvrengine.cpp
字号:
#include "StdAfx.h"#include "WarSvrEngine.h" // class implemented#if defined(WIN32) && !defined(WAR_SOCKET_IO_WIN32_NT_H)# include "WarSocketIoWin32Nt.h"#endif#ifndef WAR_SOCKET_IO_H# include "WarSocketIo.h"#endif#ifndef WAR_SVR_ENGINE_SOCKET_H# include"WarSvrEngineSocket.h"#endif#ifndef WAR_LOG_H# include "WarLog.h"#endif#ifndef WAR_SVR_PROTOCOL_H# include "WarSvrProtocol.h"#endif#ifndef WAR_SHUTDOWN_ENGINE_H# include "WarSvrEngine.h"#endif#ifndef WAR_SHUTDOWN_ENGINE_H# include "WarShutdownEngine.h"#endif#ifndef WAR_AUTO_LOCK_H# include "WarAutoLock.h"#endif#ifndef WAR_FILE_DRIVER_DYNAMIC_H# include "WarFileDriverDynamic.h"#endif#ifndef CGI_SESMGR_ACTIVITY_H# include "CgiSesmgrActivity.h"#endif#define AUTO_LOCK WarAutoLock my_lock(mLock);using namespace std;/////////////////////////////// PUBLIC ///////////////////////////////////////WarSvrEngine *WarSvrEngine::mspThis;//============================= LIFECYCLE ====================================WarSvrEngine::WarSvrEngine() : WarPluginSupport<WarSvrEngine>("WarSvrEngine"),m_bIsShuttingDown(false),mIsPaused(false){ if (mspThis != NULL) WarThrow(WarError(WAR_ERR_ALREADY_INITIALIZED), NULL); mspThis = this;}// WarSvrEngineWarSvrEngine::~WarSvrEngine(){ if (mspThis == this) mspThis = NULL;}// ~WarSvrEngine//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarSvrEngine::StartServer() throw(WarException){ WarLog err_log(WARLOG_ERROR, "WarSvrEngine::StartServer()"); for(war_svrdef_list_t::iterator P = mServices.begin() ; P != mServices.end() ; P++) { war_socket_io_ptr_t pcompanion = NewIoSocketForStartup(); try { war_svrdef_ptr_t my_svr_ptr = *P; war_socket_io_ptr_t my_companion_ptr = pcompanion; war_socket_ptr_t sck_ptr = new WarSvrEngineSocket(this, my_svr_ptr, my_companion_ptr); WarLog info_log(WARLOG_INFO, "WarSvrEngine::StartServer()", &(*sck_ptr)); info_log << "Listening to " << (*P)->GetHost().Explain() << war_endl; sck_ptr->Listen((*P)->GetHost()); mListeningTo.insert(sck_ptr); } catch(WarException& ex) { err_log << "Failed to listen to " << (*P)->Explain() << " due to exception " << ex.Explain() << war_endl; throw(ex); } }#ifdef WAR_USE_WEBADM // Initialize wfde:// handlers try { // Declare "wfde://" as a URL type WarUrlType::DefineUrlType("wfde", WarUrlType::S_GENERIC, true, true); WarPath<wchar_t> name, path, proc; WarFileDriver::driver_ptr_t wfde_ptr = WarFileEngine::GetEngine().GetDriver("wfde"); WarFileDriverDynamic *pwfde = (WarFileDriverDynamic *)&(*wfde_ptr); // Session manager "/proc" path proc = "proc"; pwfde->MountDir(proc.GetPath(), NULL); // Session manager "/proc/sesmgr" path name = "sesmgr"; pwfde->MountDir(name.GetPath(), proc.GetPath()); name = "activity.html"; path = "proc/sesmgr"; pwfde->MountFile(name.GetPath(), new WarFileDriverDynamicNodeT<CgiSesmgrActivity>, path.GetPath()); // Log module's "/proc/logs" path name = "logs"; pwfde->MountDir(name.GetPath(), proc.GetPath()); // Sites root-path "/proc/sites" name = "sites"; pwfde->MountDir(name.GetPath(), proc.GetPath()); } catch(WarException& ex) { err_log << "Failed to initialize the \"wfde://\" structure. " << ex.Explain() << ex << war_endl; }#endif WarShutdownEngine::GetEngine().AddEvent(OnShutdown, this);}void WarSvrEngine::AddServer(war_svrdef_ptr_t serverDef) throw(WarException){ if (m_bIsShuttingDown) WarThrow(WarError(WAR_ERR_ABORT_THREAD), NULL); AUTO_LOCK pair<war_svrdef_list_t::iterator, bool> result = mServices.insert(serverDef); if (!result.second) WarThrow(WarError(WAR_ERR_OBJECT_EXIST), NULL);}void WarSvrEngine::UnregisterSession(WarSvrProtocol& from){ AUTO_LOCK svrset_t::iterator P = mCurrentServers.find(&from); if (P != mCurrentServers.end()) mCurrentServers.erase(P);}void WarSvrEngine::Pause(){ WarLog info_log(WARLOG_INFO, "WarSvrEngine::Pause()"); info_log << "Entering paused operation. " "New clients will not be able to connect." << war_endl; AUTO_LOCK mIsPaused = true;}// Resume normal operationvoid WarSvrEngine::Resume(){ WarLog info_log(WARLOG_INFO, "WarSvrEngine::Resume()"); info_log << "Resuming normal operation. " << war_endl; AUTO_LOCK mIsPaused = false;}bool WarSvrEngine::CanPlay() const{ return ((mIsPaused == false) && (m_bIsShuttingDown == false));}void WarSvrEngine::Initialize() throw(WarException){#ifdef WAR_USE_WEBADM // Declare "wfde://" as a URL type WarUrlType::DefineUrlType("wfde", WarUrlType::S_GENERIC, true, true);#endif}//============================= ACCESS ===================================//============================= CALLBACK ===================================void WarSvrEngine::OnShutdown(war_cptr_t ptr){ ((WarSvrEngine *)ptr)->OnShutdown();}//============================= INQUIRY ===================================/////////////////////////////// PROTECTED ///////////////////////////////////void WarSvrEngine::OnShutdown(){ WarLog err_log(WARLOG_ERROR, "WarSvrEngine::OnShutdown()"); WarLog sys_log(WARLOG_SYSTEM, "WarSvrEngine::OnShutdown()"); { AUTO_LOCK if (m_bIsShuttingDown) return; m_bIsShuttingDown = true; } sys_log << "Shutting down sessions and services." << war_endl; // Kill listening sockets while(true) { war_socket_ptr_t sck_ptr; { AUTO_LOCK if (mListeningTo.empty()) break; sck_ptr = *(mListeningTo.begin()); mListeningTo.erase(mListeningTo.begin()); } try { // Kill it sck_ptr->Close(); sck_ptr = NULL; } catch(WarException& e) { if (e.LocalError() != WAR_ERR_SHUTDOWN) { err_log << "Caught unexpected exception " << e.Explain() << war_endl; } } } // Kill current sessions while(true) { WarPtrWrapper<WarSvrProtocol> my_session_ptr; { AUTO_LOCK if (mCurrentServers.empty()) break; my_session_ptr = *(mCurrentServers.begin()); mCurrentServers.erase(mCurrentServers.begin()); } try { my_session_ptr->Abort(WarError(WAR_ERR_SHUTDOWN)); my_session_ptr = NULL; } catch(WarException& e) { if (e.LocalError() != WAR_ERR_SHUTDOWN) { err_log << "Caught unexpected exception " << e.Explain() << war_endl; } } } // Kill servers while(true) { war_svrdef_ptr_t my_server; { AUTO_LOCK if (mServices.empty()) break; my_server = *(mServices.begin()); mServices.erase(mServices.begin()); } try { // Kill the service my_server = NULL; } catch(WarException& e) { if (e.LocalError() != WAR_ERR_SHUTDOWN) { err_log << "Caught unexpected exception " << e.Explain() << war_endl; } } } sys_log << "All sessions and services are now shut down." << war_endl;}void WarSvrEngine::OnAccept(const WarError& status, war_socket_t newSocket, const WarNetAddress& remoteAddress, const WarNetAddress& localAddress, WarSvrEngineSocket *pListenSck){ // Incoming connection WarLog net_log(WARLOG_NETWORK, "WarSvrEngine::OnAccept()"); WarLog err_log(WARLOG_ERROR, "WarSvrEngine::OnAccept()"); WAR_PLUGINS_BEGINPRC(WarSvrEngine, OnAccept, (status, newSocket, remoteAddress, localAddress, pListenSck)) return; case WAR_ERR_SECURITY_VIOLATION: goto fail; WAR_PLUGIN_ENDPRC(); if (mIsPaused) { if (!status) { net_log << "Incomming connection from " << remoteAddress.Explain() << " To " << localAddress.Explain() << " is rejected due to paused operation. " << war_endl; ::closesocket(newSocket); } return; } if (m_bIsShuttingDown) { if (!status) { net_log << "Incomming connection from " << remoteAddress.Explain() << " To " << localAddress.Explain() << " is rejected due to shutdown. " << war_endl; ::closesocket(newSocket); } return; } if (status == false) { war_svr_protocol_ptr_t session_ptr; // No error, - let's start a session :) war_socket_io_ptr_t io_socket = NewIoSocketForClient(); try { AUTO_LOCK; io_socket->AssignSocket(newSocket); session_ptr = pListenSck->GetSvrDefinition().CreateNewInstance( io_socket); } catch(WarException& ex) { closesocket(newSocket); err_log << "Failed to create server instance for the incomming connection " << remoteAddress.Explain() << " --> " << localAddress.Explain() << ex << war_endl; goto fail; } { AUTO_LOCK; session_ptr->mLocalAddress = localAddress; session_ptr->mRemoteAddress = remoteAddress; net_log << "Incomming connection from " << remoteAddress.Explain() << " --> " << localAddress.Explain() << " assigned to socket ID# " << session_ptr->GetSeqNumber() << war_endl; mCurrentServers.insert(session_ptr); } try { session_ptr->OnClientConnect(); } catch(WarException& ex) { net_log << "Incomming connection from " << remoteAddress.Explain() << " --> " << localAddress.Explain() << " assigned to socket ID# " << session_ptr->GetSeqNumber() << " failed to initialize." << ex << war_endl; goto fail; } } else { net_log << "Incomming connection from " << remoteAddress.Explain() << " --> " << localAddress.Explain() << status << " failed. " << war_endl;fail: ::closesocket(newSocket); }}WarSocketIo *WarSvrEngine::NewIoSocketForStartup() throw(WarException){#ifdef WIN32 return new WarSocketIoWin32Nt;#else return new WarSocketIo;#endif}WarSocketIo *WarSvrEngine::NewIoSocketForClient() throw(WarException){#ifdef WIN32 return new WarSocketIoWin32Nt;#else return new WarSocketIo;#endif}/////////////////////////////// PRIVATE ///////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -