303 lines
6.2 KiB
C++
303 lines
6.2 KiB
C++
#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)
|
||
{
|
||
m_loop = loop;
|
||
m_type = type;
|
||
|
||
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;
|
||
}
|
||
|
||
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->svrType == m_type);
|
||
|
||
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.svrType = p->m_type;
|
||
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
|
||
}
|
||
}
|
||
}
|