#include "WebServer.h" #include "MsgLoop.h" #include "WsUser.h" #include "HttpUser.h" #include "SockIoUser.h" #include "../../base/HGInfo.h" WebServer::WebServer(class MsgLoop* loop, HGUInt type, HGUInt id) { m_loop = loop; m_type = type; m_id = id; m_currUserId = 1; #if defined(HG_CMP_MSC) m_sockServer = INVALID_SOCKET; #else m_sockServer = -1; #endif m_listenThread = NULL; } WebServer::~WebServer() { } class MsgLoop* WebServer::GetLoop() { return m_loop; } HGUInt WebServer::GetType() { return m_type; } HGUInt WebServer::GetId() { return m_id; } bool WebServer::Open(HGUShort port) { #if defined(HG_CMP_MSC) if (INVALID_SOCKET != m_sockServer) #else if (-1 != m_sockServer) #endif { return false; } #if defined(HG_CMP_MSC) SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == sockServer) #else int sockServer = socket(AF_INET, SOCK_STREAM, 0); if (-1 == sockServer) #endif { HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "open webserver failed 1, port=%u", port); return false; } // bind #if defined(HG_CMP_MSC) SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = INADDR_ANY; addrServer.sin_family = AF_INET; addrServer.sin_port = htons(port); if (0 != bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR_IN))) #else struct sockaddr_in addrServer; addrServer.sin_addr.s_addr = htonl(INADDR_ANY); addrServer.sin_family = AF_INET; addrServer.sin_port = htons(port); if (0 != bind(sockServer, (struct sockaddr*)&addrServer, sizeof(addrServer))) #endif { #if defined(HG_CMP_MSC) closesocket(sockServer); #else close(sockServer); #endif HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "open webserver failed 2, port=%u", port); return false; } // listen if (0 != listen(sockServer, 5)) { #if defined(HG_CMP_MSC) closesocket(sockServer); #else close(sockServer); #endif HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "open webserver failed 3, port=%u", port); return false; } m_sockServer = sockServer; HGBase_OpenThread(ThreadFunc, this, &m_listenThread); assert(NULL != m_listenThread); HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "open webserver success, port=%u", port); return true; } bool WebServer::Close() { #if defined(HG_CMP_MSC) if (INVALID_SOCKET == m_sockServer) #else if (-1 == m_sockServer) #endif { return false; } while (!m_vectorUser.empty()) { WebUser* pUser = m_vectorUser[0]; m_vectorUser.erase(m_vectorUser.begin()); delete pUser; pUser = NULL; } #if defined(HG_CMP_MSC) closesocket(m_sockServer); m_sockServer = INVALID_SOCKET; #else close(m_sockServer); m_sockServer = -1; #endif HGBase_CloseThread(m_listenThread); m_listenThread = NULL; return true; } void WebServer::HandleMsg(const WebMsg* msg) { assert(NULL != msg); assert(msg->svrId == m_id); if (WEB_MSGID_CONNET == msg->msgId) { assert(0 == msg->usrId); ConnectParam* param = (ConnectParam*)msg->param; assert(NULL != param); WebUser* user = NULL; if (ServerType_Ws == m_type) user = new WsUser(this, m_currUserId, param->ip, param->port, param->socket); else if (ServerType_Http == m_type) user = new HttpUser(this, m_currUserId, param->ip, param->port, param->socket); else user = new SockIoUser(this, m_currUserId, param->ip, param->port, param->socket); // 打开接收线程 user->Open(); ++m_currUserId; m_vectorUser.push_back(user); delete param; } else if (WEB_MSGID_DISCONNET == msg->msgId) { HGUInt id = (HGUInt)msg->usrId; assert(NULL == msg->param); int nIndex = GetUserIndex(id); if (-1 != nIndex) { WebUser* pUser = m_vectorUser[nIndex]; m_vectorUser.erase(m_vectorUser.begin() + nIndex); delete pUser; pUser = NULL; } } else if (WEB_MSGID_WSCMD == msg->msgId) { HGUInt id = (HGUInt)msg->usrId; WsCmdParam* param = (WsCmdParam*)msg->param; assert(NULL != param); int nIndex = GetUserIndex(id); if (-1 != nIndex) { WsUser* user = (WsUser*)m_vectorUser[nIndex]; user->HandleCmd(param); } delete[] param->data; param->size = 0; delete param; } else if (WEB_MSGID_HTTPCMD == msg->msgId) { HGUInt id = (HGUInt)msg->usrId; HttpCmdParam* param = (HttpCmdParam*)msg->param; assert(NULL != param); int nIndex = GetUserIndex(id); if (-1 != nIndex) { HttpUser* user = (HttpUser*)m_vectorUser[nIndex]; user->HandleCmd(param); } delete[] param->data; param->size = 0; delete param; } else if (WEB_MSGID_SOCKIOCMD == msg->msgId) { HGUInt id = (HGUInt)msg->usrId; SockIoCmdParam* param = (SockIoCmdParam*)msg->param; assert(NULL != param); int nIndex = GetUserIndex(id); if (-1 != nIndex) { SockIoUser* user = (SockIoUser*)m_vectorUser[nIndex]; user->HandleCmd(param); } delete[] param->data; param->size = 0; delete param; } else if (WEB_MSGID_SOCKIORET == msg->msgId) { HGUInt id = (HGUInt)msg->usrId; SockIoRetParam* param = (SockIoRetParam*)msg->param; assert(NULL != param); int nIndex = GetUserIndex(id); if (-1 != nIndex) { SockIoUser* user = (SockIoUser*)m_vectorUser[nIndex]; user->HandleRet(param); } delete[] param->data; param->size = 0; delete param; } } int WebServer::GetUserIndex(HGUInt id) { int nIndex = -1; for (int i = 0; i < (int)m_vectorUser.size(); ++i) { if (id == m_vectorUser[i]->GetId()) { nIndex = i; break; } } return nIndex; } void WebServer::ThreadFunc(HGThread thread, HGPointer param) { WebServer* p = (WebServer*)param; while (1) { #if defined(HG_CMP_MSC) SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR_IN); SOCKET socketConn = accept(p->m_sockServer, (SOCKADDR*)&addrClient, &len); if (INVALID_SOCKET == socketConn) #else struct sockaddr_in addrClient; socklen_t len = sizeof(addrClient); int socketConn = accept(p->m_sockServer, (struct sockaddr*)&addrClient, &len); if (-1 == socketConn) #endif { // 这里跳出,可能是服务器关闭了m_sockServer break; } ConnectParam* param = new ConnectParam; strcpy(param->ip, inet_ntoa(addrClient.sin_addr)); param->port = ntohs(addrClient.sin_port); param->socket = socketConn; WebMsg msg; msg.msgId = WEB_MSGID_CONNET; msg.svrId = p->m_id; msg.usrId = 0; msg.param = param; bool b = p->m_loop->Send(&msg); if (!b) { delete msg.param; #if defined(HG_CMP_MSC) closesocket(socketConn); #else close(socketConn); #endif } } }