code_app/sdk/webservice/WebServer.cpp

303 lines
6.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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
}
}
}