2022-05-03 10:25:52 +00:00
|
|
|
|
#include "SockIoUser.h"
|
|
|
|
|
#include "WebServer.h"
|
|
|
|
|
#include "MsgLoop.h"
|
|
|
|
|
#include "Manager.h"
|
|
|
|
|
#include "../../base/HGInfo.h"
|
|
|
|
|
#include "../../base/HGUtility.h"
|
|
|
|
|
#include "sha1.h"
|
|
|
|
|
#include "base64.h"
|
|
|
|
|
#include "cJSON.h"
|
|
|
|
|
|
|
|
|
|
#if defined(HG_CMP_MSC)
|
|
|
|
|
SockIoUser::SockIoUser(class WebServer* server, HGUInt id, const char* ip, uint16_t port, SOCKET sockConn)
|
|
|
|
|
#else
|
|
|
|
|
SockIoUser::SockIoUser(class WebServer* server, HGUInt id, const char* ip, uint16_t port, int sockConn)
|
|
|
|
|
#endif
|
|
|
|
|
: WebUser(server, id, ip, port, sockConn)
|
|
|
|
|
{
|
|
|
|
|
GetManager()->SetScanEvent(ScanCallback, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SockIoUser::~SockIoUser()
|
|
|
|
|
{
|
|
|
|
|
GetManager()->ResetScanEvent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::HandleCmd(const SockIoCmdParam* param)
|
|
|
|
|
{
|
|
|
|
|
std::string user;
|
|
|
|
|
std::string data;
|
|
|
|
|
GetMsgInfo(param, user, data);
|
|
|
|
|
if (user.empty())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("scan" == user)
|
|
|
|
|
{
|
|
|
|
|
std::string imgName;
|
|
|
|
|
bool insert = false;
|
|
|
|
|
|
|
|
|
|
cJSON* json = cJSON_Parse(data.c_str());
|
|
|
|
|
if (NULL != json)
|
|
|
|
|
{
|
|
|
|
|
if (NULL != json->child && 0 == strcmp("imageName", json->child->string)
|
|
|
|
|
&& cJSON_String == json->child->type)
|
|
|
|
|
{
|
|
|
|
|
imgName = json->child->valuestring;
|
|
|
|
|
if (NULL != json->child->next && 0 == strcmp("isInsert", json->child->next->string)
|
|
|
|
|
&& cJSON_True == json->child->next->type)
|
|
|
|
|
insert = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON_Delete(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ret = GetManager()->Scan(imgName, insert);
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
std::string resp = "42[\"error\", \"scan error\"]";
|
|
|
|
|
SendResponse((const HGByte*)resp.c_str(), (HGUInt)resp.size(), HGTRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ("stop" == user)
|
|
|
|
|
{
|
|
|
|
|
bool ret = GetManager()->StopScan();
|
|
|
|
|
assert(ret);
|
|
|
|
|
|
|
|
|
|
std::string resp = "42[\"success\", \"stop scan success!\"]";
|
|
|
|
|
SendResponse((const HGByte*)resp.c_str(), (HGUInt)resp.size(), HGTRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::HandleRet(const SockIoRetParam* param)
|
|
|
|
|
{
|
|
|
|
|
SendResponse(param->data, param->size, HGTRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::ThreadFunc()
|
|
|
|
|
{
|
|
|
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SockIoUser::ThreadFunc");
|
|
|
|
|
|
|
|
|
|
char chBuffer[2048];
|
|
|
|
|
const char* pBuffer = chBuffer;
|
|
|
|
|
int nBufferSize = 0;
|
|
|
|
|
bool bConnect = false;
|
|
|
|
|
|
|
|
|
|
unsigned char connectDataTail[4] = { '\r', '\n', '\r', '\n' };
|
|
|
|
|
unsigned int connectDataTailLen = 0;
|
|
|
|
|
std::string connectData;
|
|
|
|
|
|
|
|
|
|
uint8_t* pData = NULL;
|
|
|
|
|
int nDataSize = 0;
|
|
|
|
|
uint8_t* pDataEx = NULL;
|
|
|
|
|
int nRemainSize = 0;
|
|
|
|
|
uint8_t headData[20];
|
|
|
|
|
uint32_t nHeadDataLen = 0;
|
|
|
|
|
uint8_t vMask[4];
|
|
|
|
|
uint32_t nMaskCount = 0;
|
|
|
|
|
bool bHandle = false;
|
|
|
|
|
std::vector<uint8_t> vAllData;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (0 == nBufferSize)
|
|
|
|
|
{
|
|
|
|
|
int len = recv(m_sockConn, chBuffer, 2048, 0);
|
|
|
|
|
if (len <= 0)
|
|
|
|
|
{
|
|
|
|
|
// 这里跳出,可能是服务器关闭了socketConn,或者客户端关闭了socket,或者网络断开
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pBuffer = chBuffer;
|
|
|
|
|
nBufferSize = len;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(nBufferSize > 0);
|
|
|
|
|
|
|
|
|
|
if (!bConnect)
|
|
|
|
|
{
|
|
|
|
|
unsigned char b = *pBuffer;
|
|
|
|
|
++pBuffer;
|
|
|
|
|
--nBufferSize;
|
|
|
|
|
|
|
|
|
|
connectData.push_back(b);
|
|
|
|
|
if (b == connectDataTail[connectDataTailLen])
|
|
|
|
|
{
|
|
|
|
|
++connectDataTailLen;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
connectDataTailLen = 0;
|
|
|
|
|
if (b == connectDataTail[connectDataTailLen])
|
|
|
|
|
{
|
|
|
|
|
++connectDataTailLen;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (4 == connectDataTailLen)
|
|
|
|
|
{
|
|
|
|
|
connectDataTailLen = 0;
|
|
|
|
|
bool shakeRet = ShakeHand(connectData);
|
|
|
|
|
connectData.clear();
|
|
|
|
|
|
|
|
|
|
if (!shakeRet)
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bConnect = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (NULL == pData)
|
|
|
|
|
{
|
|
|
|
|
assert(0 == nDataSize);
|
|
|
|
|
|
|
|
|
|
uint8_t b = *pBuffer;
|
|
|
|
|
++pBuffer;
|
|
|
|
|
--nBufferSize;
|
|
|
|
|
headData[nHeadDataLen] = b;
|
|
|
|
|
++nHeadDataLen;
|
|
|
|
|
|
|
|
|
|
if (1 == nHeadDataLen)
|
|
|
|
|
{
|
|
|
|
|
if ((0x80 | 0x08) == headData[0]) // 断开连接
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if ((0x80 | 0x09) == headData[0]) // PING帧
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
else if ((0x00 | 0x01) == headData[0] || (0x00 | 0x02) == headData[0] || (0x00 | 0x00) == headData[0] || (0x80 | 0x00) == headData[0]
|
|
|
|
|
|| (0x80 | 0x01) == headData[0] || (0x80 | 0x02) == headData[0]) // 数据帧
|
|
|
|
|
{
|
|
|
|
|
if ((0x80 | 0x00) == headData[0] || (0x80 | 0x01) == headData[0] || (0x80 | 0x02) == headData[0])
|
|
|
|
|
{
|
|
|
|
|
// 分片结束
|
|
|
|
|
bHandle = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 分片帧
|
|
|
|
|
bHandle = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // 帧错误,断开连接
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (2 == nHeadDataLen)
|
|
|
|
|
{
|
|
|
|
|
if (0 == (headData[1] & 0x80)) // 必须经过掩码处理
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((0x80 | 0x09) == headData[0]) // PING帧
|
|
|
|
|
{
|
|
|
|
|
if (0x80 != headData[1])
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
|
|
|
|
{
|
|
|
|
|
if (0x80 != headData[1])
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((headData[1] & 0x7F) <= 125)
|
|
|
|
|
{
|
|
|
|
|
uint32_t nCmdSize = (headData[1] & 0x7F);
|
|
|
|
|
nHeadDataLen = 0;
|
|
|
|
|
|
|
|
|
|
if (0 == nCmdSize)
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nDataSize = nCmdSize;
|
|
|
|
|
nRemainSize = nCmdSize;
|
|
|
|
|
pData = new uint8_t[nDataSize];
|
|
|
|
|
pDataEx = pData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (4 == nHeadDataLen)
|
|
|
|
|
{
|
|
|
|
|
if ((0x80 | 0x09) == headData[0]) // PING帧
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((headData[1] & 0x7F) == 126)
|
|
|
|
|
{
|
|
|
|
|
uint32_t nCmdSize = ntohs(*(uint16_t*)&headData[2]);
|
|
|
|
|
nHeadDataLen = 0;
|
|
|
|
|
|
|
|
|
|
if (0 == nCmdSize)
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nDataSize = nCmdSize;
|
|
|
|
|
nRemainSize = nCmdSize;
|
|
|
|
|
pData = new uint8_t[nDataSize];
|
|
|
|
|
pDataEx = pData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (6 == nHeadDataLen)
|
|
|
|
|
{
|
|
|
|
|
if ((0x80 | 0x09) == headData[0]) // PING帧
|
|
|
|
|
{
|
|
|
|
|
nHeadDataLen = 0;
|
|
|
|
|
|
|
|
|
|
Pong();
|
|
|
|
|
}
|
|
|
|
|
else if ((0x80 | 0x0A) == headData[0]) // PONG帧
|
|
|
|
|
{
|
|
|
|
|
nHeadDataLen = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (10 == nHeadDataLen)
|
|
|
|
|
{
|
|
|
|
|
if ((headData[1] & 0x7F) == 127) // 这里一定会等于127
|
|
|
|
|
{
|
|
|
|
|
uint32_t nCmdSizeHigh = ntohl(*(uint32_t*)&headData[2]);
|
|
|
|
|
uint32_t nCmdSize = ntohl(*(uint32_t*)&headData[6]);
|
|
|
|
|
nHeadDataLen = 0;
|
|
|
|
|
|
|
|
|
|
if ((0 != nCmdSizeHigh) || (0 == nCmdSize))
|
|
|
|
|
{
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_DISCONNET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = NULL;
|
|
|
|
|
GetLoop()->Send(&msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nDataSize = nCmdSize;
|
|
|
|
|
nRemainSize = nCmdSize;
|
|
|
|
|
pData = new uint8_t[nDataSize];
|
|
|
|
|
pDataEx = pData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (4 != nMaskCount)
|
|
|
|
|
{
|
|
|
|
|
uint8_t b = *pBuffer;
|
|
|
|
|
++pBuffer;
|
|
|
|
|
--nBufferSize;
|
|
|
|
|
vMask[nMaskCount] = b;
|
|
|
|
|
++nMaskCount;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int nWriteSize = HGMIN(nBufferSize, nRemainSize);
|
|
|
|
|
memcpy(pDataEx, pBuffer, nWriteSize);
|
|
|
|
|
pBuffer += nWriteSize;
|
|
|
|
|
nBufferSize -= nWriteSize;
|
|
|
|
|
pDataEx += nWriteSize;
|
|
|
|
|
nRemainSize -= nWriteSize;
|
|
|
|
|
|
|
|
|
|
if (0 == nRemainSize)
|
|
|
|
|
{
|
|
|
|
|
assert(pDataEx == pData + nDataSize);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < nDataSize; ++i)
|
|
|
|
|
{
|
|
|
|
|
int j = i % 4;
|
|
|
|
|
pData[i] = pData[i] ^ vMask[j];
|
|
|
|
|
vAllData.push_back(pData[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete[] pData;
|
|
|
|
|
pData = NULL;
|
|
|
|
|
nDataSize = 0;
|
|
|
|
|
nMaskCount = 0;
|
|
|
|
|
|
|
|
|
|
if (bHandle)
|
|
|
|
|
{
|
|
|
|
|
if (1 == vAllData.size() && '2' == vAllData[0])
|
|
|
|
|
{
|
|
|
|
|
// socket.io pong
|
|
|
|
|
char data = '3';
|
|
|
|
|
SendResponse((const HGByte*)&data, 1, HGTRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SockIoCmdParam* param = new SockIoCmdParam;
|
|
|
|
|
param->data = new HGByte[vAllData.size()];
|
|
|
|
|
param->size = (HGUInt)vAllData.size();
|
|
|
|
|
memcpy(param->data, &vAllData[0], vAllData.size());
|
|
|
|
|
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_SOCKIOCMD;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = m_id;
|
|
|
|
|
msg.param = param;
|
|
|
|
|
bool b = GetLoop()->Send(&msg);
|
|
|
|
|
if (!b)
|
|
|
|
|
{
|
|
|
|
|
delete[] param->data;
|
|
|
|
|
param->size = 0;
|
|
|
|
|
delete param;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bHandle = false;
|
|
|
|
|
vAllData.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != pData)
|
|
|
|
|
{
|
|
|
|
|
delete[] pData;
|
|
|
|
|
pData = NULL;
|
|
|
|
|
nDataSize = 0;
|
|
|
|
|
nMaskCount = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::ScanCallback(HGUInt event, void* value1, void* value2, void* param)
|
|
|
|
|
{
|
|
|
|
|
SockIoUser* p = (SockIoUser*)param;
|
|
|
|
|
|
|
|
|
|
char *resp = NULL;
|
|
|
|
|
if (SCANEVENT_ARRIVE == event)
|
|
|
|
|
{
|
|
|
|
|
resp = new char[256];
|
|
|
|
|
sprintf(resp, "42[\"success\", \"%s\"]", (const char*)value1);
|
|
|
|
|
}
|
|
|
|
|
else if (SCANEVENT_REMOVE == event)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (SCANEVENT_WORKING == event)
|
|
|
|
|
{
|
|
|
|
|
resp = new char[256];
|
|
|
|
|
sprintf(resp, "42[\"event\", \"%s\"]", "......");
|
|
|
|
|
}
|
|
|
|
|
else if (SCANEVENT_FINISH == event)
|
|
|
|
|
{
|
|
|
|
|
resp = new char[256];
|
|
|
|
|
sprintf(resp, "42[\"result\", {\"code\":204, \"msg\":\"%s\"}]", (const char *)value1);
|
|
|
|
|
}
|
|
|
|
|
else if (SCANEVENT_ERROR == event)
|
|
|
|
|
{
|
|
|
|
|
resp = new char[256];
|
|
|
|
|
sprintf(resp, "42[\"error\", \"%s\"]", (const char*)value1);
|
|
|
|
|
}
|
|
|
|
|
else if (SCANEVENT_IMAGE == event)
|
|
|
|
|
{
|
|
|
|
|
const char* imgName = (const char*)value1;
|
|
|
|
|
const char* imgBase64 = (const char*)value2;
|
|
|
|
|
resp = new char[256 + strlen(imgName) + strlen(imgBase64)];
|
|
|
|
|
sprintf(resp, "42[\"image\", {\"code\":201, \"imageName\":\"%s\", \"image\":\"%s\"}]", imgName, imgBase64);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != resp)
|
|
|
|
|
{
|
|
|
|
|
SockIoRetParam* param = new SockIoRetParam;
|
|
|
|
|
param->data = new HGByte[strlen(resp)];
|
|
|
|
|
param->size = (HGUInt)strlen(resp);
|
|
|
|
|
memcpy(param->data, resp, strlen(resp));
|
|
|
|
|
|
|
|
|
|
WebMsg msg;
|
|
|
|
|
msg.msgId = WEB_MSGID_SOCKIORET;
|
2022-05-09 10:58:09 +00:00
|
|
|
|
msg.svrType = p->m_server->GetType();
|
2022-05-03 10:25:52 +00:00
|
|
|
|
msg.usrId = p->m_id;
|
|
|
|
|
msg.param = param;
|
|
|
|
|
bool b = p->GetLoop()->Send(&msg);
|
|
|
|
|
if (!b)
|
|
|
|
|
{
|
|
|
|
|
delete[] param->data;
|
|
|
|
|
param->size = 0;
|
|
|
|
|
delete param;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete[] resp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::GetMsgInfo(const SockIoCmdParam* param, std::string& user, std::string& data)
|
|
|
|
|
{
|
|
|
|
|
user.clear();
|
|
|
|
|
data.clear();
|
|
|
|
|
|
|
|
|
|
std::string paramStr((const char *)param->data, param->size);
|
|
|
|
|
size_t pos = paramStr.find('[');
|
|
|
|
|
if (std::string::npos == pos)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string msgType = paramStr.substr(0, pos);
|
|
|
|
|
if ("42" != msgType)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string msgInfo = paramStr.substr(pos);
|
|
|
|
|
cJSON* json = cJSON_Parse(msgInfo.c_str());
|
|
|
|
|
if (NULL != json)
|
|
|
|
|
{
|
|
|
|
|
if (NULL != json->child)
|
|
|
|
|
{
|
|
|
|
|
user = json->child->valuestring;
|
|
|
|
|
if (NULL != json->child->next)
|
|
|
|
|
data = json->child->next->valuestring;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON_Delete(json);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SockIoUser::ShakeHand(const std::string& head)
|
|
|
|
|
{
|
|
|
|
|
std::string requestMethod;
|
|
|
|
|
std::string requestURIPath;
|
|
|
|
|
HttpPairs requestURIQueryInfos;
|
|
|
|
|
std::string requestURIFragment;
|
|
|
|
|
std::string httpVersion;
|
|
|
|
|
HttpPairs headInfos;
|
|
|
|
|
HttpHead::AnalysisHead(head, requestMethod, requestURIPath, requestURIQueryInfos,
|
|
|
|
|
requestURIFragment, httpVersion, headInfos);
|
|
|
|
|
|
|
|
|
|
if ("websocket" != HttpHead::GetValue(requestURIQueryInfos, "transport"))
|
|
|
|
|
return false;
|
|
|
|
|
if ("Upgrade" != HttpHead::GetValue(headInfos, "Connection"))
|
|
|
|
|
return false;
|
|
|
|
|
if ("websocket" != HttpHead::GetValue(headInfos, "Upgrade"))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
std::string key = HttpHead::GetValue(headInfos, "Sec-WebSocket-Key");
|
|
|
|
|
if (key.empty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
|
|
|
|
|
|
|
|
unsigned int message_digest[5];
|
|
|
|
|
SHA1 sha;
|
|
|
|
|
sha.Reset();
|
|
|
|
|
sha << key.c_str();
|
|
|
|
|
sha.Result(message_digest);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 5; ++i)
|
|
|
|
|
message_digest[i] = htonl(message_digest[i]);
|
|
|
|
|
std::string serverKey = base64_encode((const unsigned char*)message_digest, 20);
|
|
|
|
|
|
|
|
|
|
std::string handShakeResp = "HTTP/1.1 101 Switching Protocols\r\n";
|
|
|
|
|
handShakeResp += "Upgrade: websocket\r\n";
|
|
|
|
|
handShakeResp += "Connection: Upgrade\r\n";
|
|
|
|
|
handShakeResp += "Sec-WebSocket-Accept:";
|
|
|
|
|
handShakeResp += serverKey;
|
|
|
|
|
handShakeResp += "\r\n\r\n";
|
|
|
|
|
send(m_sockConn, handShakeResp.c_str(), (int)handShakeResp.length(), 0);
|
|
|
|
|
|
|
|
|
|
char uuid[256] = {0};
|
|
|
|
|
HGBase_GetUuid(uuid, 256);
|
|
|
|
|
|
|
|
|
|
std::string resp = "0{";
|
|
|
|
|
resp += "\"sid\":\"";
|
|
|
|
|
resp += uuid;
|
|
|
|
|
resp += "\",";
|
|
|
|
|
resp += "\"upgrades\":[\"websocket\"],";
|
|
|
|
|
resp += "\"pingInterval\":25000,";
|
|
|
|
|
resp += "\"pingTimeout\":60000";
|
|
|
|
|
resp += "}";
|
|
|
|
|
SendResponse((const HGByte*)resp.c_str(), (int)resp.size(), HGTRUE);
|
|
|
|
|
|
|
|
|
|
resp = "40";
|
|
|
|
|
SendResponse((const HGByte*)resp.c_str(), (int)resp.size(), HGTRUE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SockIoUser::Pong()
|
|
|
|
|
{
|
|
|
|
|
uint8_t vHead[2];
|
|
|
|
|
vHead[0] = 0x80 | 0x0A;
|
|
|
|
|
vHead[1] = 0;
|
|
|
|
|
|
|
|
|
|
HGBase_EnterLock(m_cs);
|
|
|
|
|
send(m_sockConn, (const char*)vHead, 2, 0);
|
|
|
|
|
HGBase_LeaveLock(m_cs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SockIoUser::SendResponse(const HGByte* data, HGUInt size, HGBool text)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == data || 0 == size)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t nHeadLen = 0;
|
|
|
|
|
|
|
|
|
|
uint8_t vHead[20] = { 0 };
|
|
|
|
|
vHead[0] = text ? (0x80 | 0x01) : (0x80 | 0x02);
|
|
|
|
|
if (size <= 125)
|
|
|
|
|
{
|
|
|
|
|
vHead[1] = (uint8_t)size;
|
|
|
|
|
nHeadLen = 2;
|
|
|
|
|
}
|
|
|
|
|
else if (size <= 0xFFFF)
|
|
|
|
|
{
|
|
|
|
|
vHead[1] = 126;
|
|
|
|
|
uint16_t payloadLength16b = htons((uint16_t)size);
|
|
|
|
|
memcpy(&vHead[2], &payloadLength16b, 2);
|
|
|
|
|
nHeadLen = 4;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vHead[1] = 127;
|
|
|
|
|
vHead[2] = 0;
|
|
|
|
|
vHead[3] = 0;
|
|
|
|
|
vHead[4] = 0;
|
|
|
|
|
vHead[5] = 0;
|
|
|
|
|
uint32_t payloadLength32b = htonl(size);
|
|
|
|
|
memcpy(&vHead[6], &payloadLength32b, 4);
|
|
|
|
|
nHeadLen = 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGBase_EnterLock(m_cs);
|
|
|
|
|
send(m_sockConn, (const char*)vHead, nHeadLen, 0);
|
|
|
|
|
send(m_sockConn, (const char*)data, size, 0);
|
|
|
|
|
HGBase_LeaveLock(m_cs);
|
|
|
|
|
return true;
|
|
|
|
|
}
|