#include "stdafx.h" #if (defined _WIN32 || defined _WIN64) #else #include #include #endif #include "CWebsocketServer.h" #include "baseEx.h" #include "CModTools.h" #include #include "MessageType.h" #include #include #include #include #include #include "../mod_guiconsole/GUIConsole_msg_g.h" #define DEFAULT_SERVER_PORT 9002 #define DEFAULT_SERVER_WS_SM2_PORT 9003 #define DEFUALT_SERVER_WSS_PORT 9004 namespace Chromium { server m_wsserver, m_ws_sm2_server; server_wss m_server_wss; CWebsocketServer::CWebsocketServer(const char* strPath, CEntityBase* pEntity) : m_ios(), m_serializer(NULL), m_socket(NULL), m_pEntity(pEntity), m_initSuccess(false) { this->m_pEntity = pEntity; m_socket = new CSocketClient(m_ios, "127.0.0.1", "4504", pEntity, 0); m_socket->SetMessageHandler(this); // Initialize serializer DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Initialize serializer"); this->m_serializer = CWSCodec::getInstance(); this->m_serializer->setEntityHandler(pEntity->GetFunction()); this->m_serializer->init(strPath); while (Error_Succeed != m_socket->Connect()) Sleep(100); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("init Entity Session Manager"); myTest(); try { m_esm = new EntitySessionManager(); } catch (const std::bad_alloc& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer::CWebsocketServer Memory allocation failed: %s", e.what()); } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer::CWebsocketServer Error: %s", e.what()); } init_websocket(); init_entity_sessions(); } void CWebsocketServer::updateMsgPool(std::string entityName, std::string& payload, websocketpp::connection_hdl hdl) { //存储的消息应具备时效性,保证一个hdl只有一个记录的消息 auto it = m_msg_pool.find(entityName); if (it != m_msg_pool.end()) { auto& curArr = it->second; for (auto i = curArr.begin(); i != curArr.end(); i++) { if (&hdl == &i->first) { curArr.erase(i); break; } } it->second.emplace_back(std::make_pair(hdl, payload)); } else { std::vector> t_saveMsgs; t_saveMsgs.emplace_back(std::make_pair(hdl, payload)); m_msg_pool.insert(std::make_pair(entityName, t_saveMsgs)); } } void CWebsocketServer::updateNotifyPool(unsigned hdl, unsigned transId) { auto it = m_notifyPool.find(hdl); if (it != m_notifyPool.end()) { if (transId == 0) m_notifyPool.erase(it); else it->second = transId; } else if (transId != 0) m_notifyPool.insert(std::make_pair(hdl, transId)); } void CWebsocketServer::storeEntityWithCLass(std::string entityName, std::string entityClass) { if (m_entityAndClass.end() == m_entityAndClass.find(entityName)) { m_entityAndClass.insert(std::make_pair(entityName, entityClass)); //not exist //DbgEx("storeEntityWithCLass, %s:%s", entityName.c_str(), entityClass.c_str()); } } std::pair CWebsocketServer::getEntityClass(std::string entityName) { auto it = m_entityAndClass.find(entityName); if (m_entityAndClass.end() == it) return std::make_pair(false, ""); else return std::make_pair(true, it->second); } void CWebsocketServer::do_sendJsonStartSession(std::string entityName, std::string entityClass) { auto startSessionReq = m_esm->GetStartSessionRequest(entityName, entityClass); auto sessionBuf = this->m_serializer->JsonToBuffer(startSessionReq.second).second; if (nullptr == sessionBuf) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("JsonToBuffer return NULL !"); return; } m_esm->StoreSessionReq(startSessionReq.first, entityName); m_esm->MakeNewTransID(sessionBuf, 0); //保存msg,先建立session if (m_esm->checkBeginSession(entityName)) { m_esm->updateBeginSessionTime(entityName); WriteToFramework(sessionBuf); } else DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Already begin session in 5s, %s", entityName.c_str()); } void CWebsocketServer::WriteToFramework(CMessage* msg) { m_socket->Write(msg); } void CWebsocketServer::deal_webchromium_msg(std::string& payload, websocketpp::connection_hdl hdl, int messageType) { switch (messageType) { case RegisterNotify: { std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); const char* transId_nodeName = "transId"; auto transid = json_deal::getIntergerFromCjsonObj(pJson.get(), transId_nodeName); if (transid.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("deal_webchromium_msg err, transIdJson == null"); return; } updateNotifyPool((long)hdl.lock().get(), transid.second); } break; case UnRegisterNotify: updateNotifyPool((long)hdl.lock().get(), 0); break; default: break; } } void CWebsocketServer::deal_logMsg(std::string& payload, websocketpp::connection_hdl hdl, int messageType) { std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); if (nullptr == pJson.get()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> deal_logMsg, jsonErr:%s", payload.c_str()); return; } auto changeMessageTypeToLogLevel = [](int messageType) ->LOG_LEVEL_E { switch (messageType) { case METHOD_SYSTEM_LOG_DEBUG: case METHOD_SYSTEM_DETAIL_LOG_DEBUG: return LOG_LEVEL_DEBUG; case METHOD_SYSTEM_LOG_INFO: case METHOD_SYSTEM_DETAIL_LOG_INFO: return LOG_LEVEL_INFO; case METHOD_SYSTEM_LOG_WARN: case METHOD_SYSTEM_DETAIL_LOG_WARN: return LOG_LEVEL_WARN; case METHOD_SYSTEM_LOG_ERROR: case METHOD_SYSTEM_DETAIL_LOG_ERROR: return LOG_LEVEL_ERROR; default: return LOG_LEVEL_DEBUG; } }; switch (messageType) { case METHOD_SYSTEM_LOG_DEBUG: case METHOD_SYSTEM_LOG_INFO: case METHOD_SYSTEM_LOG_WARN: case METHOD_SYSTEM_LOG_ERROR: { const char* msg_nodeName = "msg"; auto msg = json_deal::getStringFromCjsonObj(pJson.get(), msg_nodeName); if (!msg.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", msg_nodeName); break; } DbgWithLink(changeMessageTypeToLogLevel(messageType), LOG_TYPE_BUSINESS_SYSTEM) .withLogProducer(logProducer).setAPI("logMsg").withExtendLog(false).setResultMsg(msg.second.GetData())(); break; } case METHOD_SYSTEM_DETAIL_LOG_DEBUG: case METHOD_SYSTEM_DETAIL_LOG_INFO: case METHOD_SYSTEM_DETAIL_LOG_WARN: case METHOD_SYSTEM_DETAIL_LOG_ERROR: { const char* msg_nodeName = "ResultMsg"; const char* msg_EntityName = "EntityName"; const char* msg_logType = "LogType"; const char* msg_CostTime = "CostTime"; const char* msg_ResultCode = "ResultCode"; const char* msg_LogCode = "LogCode"; const char* msg_API = "API"; const char* msg_SourceType = "SourceType"; const char* msg_BussID = "BussID"; const char* msg_TipMsg = "TipMsg"; const char* msg_BeginTime = "BeginTime"; const char* msg_EndTime = "EndTime"; const char* msg_CmptId = "CmptId"; const char* msg_CmptName = "CmptName"; auto msg = json_deal::getStringFromCjsonObj(pJson.get(), msg_nodeName); if (!msg.first)//must have { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", msg_nodeName); break; } auto t_entityName = json_deal::getStringFromCjsonObj(pJson.get(), msg_EntityName); if(!t_entityName.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", msg_EntityName); break; } //create the logProduer if not exist if (g_logProducerArr.find(t_entityName.second.GetData()) == g_logProducerArr.end())//can not find the logProducer { auto t_CmptId = json_deal::getStringFromCjsonObj(pJson.get(), msg_CmptId); auto t_CmptName = json_deal::getStringFromCjsonObj(pJson.get(), msg_CmptName); void *t_producer = create_log_producer_storage(t_entityName.second.GetData(), "0", "", t_CmptId.second.GetData(), t_CmptName.second.GetData()); if (!t_producer) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create producer failed, %s", t_entityName.second.GetData()); break; } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create producer sueccess, entityName:%s, CmptId:%s, t_CmptName:%s" , t_entityName.second.GetData(), t_CmptId.second.GetData(), t_CmptName.second.GetData()); g_logProducerArr.insert(std::make_pair(t_entityName.second.GetData(), t_producer)); } auto t_logProducer = g_logProducerArr[t_entityName.second.GetData()]; auto logType = json_deal::getStringFromCjsonObj(pJson.get(), msg_logType);//it can be equal to Sys/User/VTMWeb LOG_TYPE_E t_type = LOG_TYPE_SYSTEM; if (logType.second.Compare("User", true) == 0) t_type = LOG_TYPE_USER; else if (logType.second.Compare("VTMWeb", true) == 0) t_type = LOG_TYPE_VTMWEB; else if(logType.second.Compare("Sys", true) == 0) t_type = LOG_TYPE_SYSTEM; //通过变量方式进行处理 DbgWithLink t_obj(changeMessageTypeToLogLevel(messageType), t_type); t_obj.withExtendLog(false); t_obj.withLogProducer(t_logProducer); t_obj.setResultMsg(msg.second.GetData()); auto t_costTime = json_deal::getIntergerFromCjsonObj(pJson.get(), msg_CostTime); if (t_costTime.first) t_obj.setCostTime(t_costTime.second); auto t_resultCode = json_deal::getStringFromCjsonObj(pJson.get(), msg_ResultCode); if (t_resultCode.first) t_obj.setResultCode(t_resultCode.second.GetData()); auto t_logcode = json_deal::getStringFromCjsonObj(pJson.get(), msg_LogCode); if (t_logcode.first) t_obj.setLogCode(t_logcode.second.GetData()); auto t_api = json_deal::getStringFromCjsonObj(pJson.get(), msg_API); if (t_api.first) t_obj.setAPI(t_api.second.GetData()); auto t_sourceType = json_deal::getStringFromCjsonObj(pJson.get(), msg_SourceType); if (t_sourceType.first) t_obj.setSourceType(t_sourceType.second.GetData()); auto t_BussID = json_deal::getStringFromCjsonObj(pJson.get(), msg_BussID); if (t_BussID.first) t_obj.setBussID(t_BussID.second.GetData()); auto t_TipMsg = json_deal::getStringFromCjsonObj(pJson.get(), msg_TipMsg); if (t_TipMsg.first) t_obj.setTipMsg(t_TipMsg.second.GetData()); auto t_BeginTime = json_deal::getIntergerFromCjsonObj(pJson.get(), msg_BeginTime); if (t_BeginTime.first) t_obj.setBeginTime(t_BeginTime.second); auto t_EndTime = json_deal::getIntergerFromCjsonObj(pJson.get(), msg_EndTime); if (t_EndTime.first) t_obj.setEndTime(t_EndTime.second); t_obj(); break; } case METHOD_BEIDOU_LOG: { //DbgEx("receive beidou msg:%s", payload.c_str()); const char* BusinessId_nodeName = "BusinessId"; const char* TraceId_nodeName = "TraceId"; const char* SpanId_nodeName = "SpanId"; const char* ParentSpanId_nodeName = "ParentSpanId"; const char* Timestamp_nodeName = "Timestamp"; const char* Host_nodeName = "Host"; const char* CallStack_nodeName = "CallStack"; const char* DbStack_nodeName = "DbStack"; const char* ReturnCode_nodeName = "ReturnCode"; const char* Tags_nodeName = "Tags"; const char* API_nodeName = "API"; const char* deployUnitId_nodeName = "deployUnitId"; const char* serviceUintId_nodeName = "serviceUintId"; auto BusinessId = json_deal::getStringFromCjsonObj(pJson.get(), BusinessId_nodeName); if (!BusinessId.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", BusinessId_nodeName); break; } auto TraceId = json_deal::getStringFromCjsonObj(pJson.get(), TraceId_nodeName); if (!TraceId.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", TraceId_nodeName); break; } auto SpanId = json_deal::getStringFromCjsonObj(pJson.get(), SpanId_nodeName); if (!SpanId.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", SpanId_nodeName); break; } auto ParentSpanId = json_deal::getStringFromCjsonObj(pJson.get(), ParentSpanId_nodeName); if (!ParentSpanId.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not has node %s", ParentSpanId_nodeName); break; } linkContext cur(BusinessId.second.GetData(), TraceId.second.GetData(), SpanId.second.GetData(), ParentSpanId.second.GetData()); auto API = json_deal::getStringFromCjsonObj(pJson.get(), API_nodeName); if (!API.first) API.second = ""; DbgToBeidou obj(cur, API.second.GetData()); auto Timestamp = json_deal::getStringFromCjsonObj(pJson.get(), Timestamp_nodeName); if (!Timestamp.first) Timestamp.second = ""; else if(Timestamp.second.GetLength() > 0) obj.setResponseTime(Timestamp.second); auto Host = json_deal::getStringFromCjsonObj(pJson.get(), Host_nodeName); if (!Host.first) Host.second = ""; else if (Host.second.GetLength() > 0) obj.setHost(Host.second); auto CallStack = json_deal::getStringFromCjsonObj(pJson.get(), CallStack_nodeName); if (!CallStack.first) CallStack.second = ""; else if (CallStack.second.GetLength() > 0) obj.setCallStack(CallStack.second); auto DbStack = json_deal::getStringFromCjsonObj(pJson.get(), DbStack_nodeName); if (!DbStack.first) DbStack.second = ""; else if (DbStack.second.GetLength() > 0) obj.setCallStack(DbStack.second); auto ReturnCode = json_deal::getStringFromCjsonObj(pJson.get(), ReturnCode_nodeName); if (!ReturnCode.first) ReturnCode.second = ""; else if (ReturnCode.second.GetLength() > 0) obj.setReturnCode(ReturnCode.second); auto Tags = json_deal::getStringFromCjsonObj(pJson.get(), Tags_nodeName); if (!Tags.first) Tags.second = ""; else if (Tags.second.GetLength() > 0) obj.setTags(Tags.second); auto deployUnitId = json_deal::getStringFromCjsonObj(pJson.get(), deployUnitId_nodeName); if (!deployUnitId.first) deployUnitId.second = ""; else if (deployUnitId.second.GetLength() > 0) obj.set_deployUnitId(deployUnitId.second); auto serviceUintId = json_deal::getStringFromCjsonObj(pJson.get(), serviceUintId_nodeName); if (!serviceUintId.first) serviceUintId.second = ""; else if (serviceUintId.second.GetLength() > 0) obj.set_serviceUnitId(serviceUintId.second); obj(); break; } default: break; } } void CWebsocketServer::deal_sessionBreakMsg(std::string& payload, websocketpp::connection_hdl hdl) { std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); if (nullptr == pJson.get()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> deal_sessionBreakMsg, jsonErr:%s", payload.c_str()); return; } auto transidNum = json_deal::getIntergerFromCjsonObj(pJson.get(), "transId"); if (transidNum.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer::deal_sessionBreakMs get transId failed"); return; } std::string sessionId = std::to_string((LONGLONG)-1); std::string transid = std::to_string((LONGLONG)transidNum.second); /* std::string js = "{\"messageType\":5,\"errorCode\":\"1537\",\"errorMsg\":\"session break\",\"sessionID\":"; js.append(sessionId.c_str()); js.append(",\"transID\":"); js.append(transid.c_str()); js.append("}"); */ std::string js = CSimpleString::Format("{\"messageType\":5,\"errorCode\":\"%d\",\"errorMsg\":\"1537 session break\",\"sessionID\":-1,\"transID\":125}", Error_DevNotAvailable).GetData(); js = restroreTransId(js); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("deal_sessionBreakMsg, len:%d, srcPayLoad:%s, ret:%s", payload.length() , payload.length() > 800 ? payload.substr(0, 800).append("...").c_str() : payload.c_str(), js.c_str()); do_send_msg(hdl, js); } void CWebsocketServer::deal_msg(std::string& payload, websocketpp::connection_hdl hdl) { boost::lock_guard lock(m_dealMsgLock); //在buffer和json处理时,deal_msg会调用多次,导致transId存在重复可能 auto ret = this->m_serializer->JsonToBuffer(payload); CMessage* p = ret.second; if (ret.first == Broadcast && nullptr == p) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("JsonToBuffer return NULL, perhaps an event happened"); do_sendJsonBroadcast(payload); return; } else if(ret.first == Request || ret.first == Info) { if(nullptr == p) { //can not find the method std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); auto transIdJson = json_deal::getIntergerFromCjsonObj(pJson.get(), "transId"); if (transIdJson.first) { std::string errRetJs = "{\"messageType\":4,\"transID\":" + std::to_string((LONGLONG)transIdJson.second) + ",\"errorCode\":103,\"errorMsg\":\"can not find entity or class!\"}"; auto js = restroreTransId(errRetJs); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("deal_msg %s get null msg, ret:%s", ret.first == Request ? "Request" : "Info", errRetJs.c_str()); do_send_msg(hdl, js); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer::deal_msg get transIdJson failed"); return; } } else if (ret.first == GetSession) { std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); auto transIdJson = json_deal::getIntergerFromCjsonObj(pJson.get(), "transId"); if (transIdJson.first) { int transid = transIdJson.second; CSystemRunInfo sysruninfo; m_pEntity->GetFunction()->GetSystemRunInfo(sysruninfo); auto sessionRet = m_esm->GetAllSessionRequest(transid, sysruninfo.bBasicCfgWork); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("sessionJson:%s", sessionRet.second.c_str()); if (sessionRet.first) { auto js = restroreTransId(sessionRet.second); do_send_msg(hdl, js); } } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer::deal_msg get transIdJson failed"); return; } else if (ret.first == BeginSession) storeEntityWithCLass(m_serializer->GetEntityName(payload), m_serializer->GetClassName(payload)); // Try to manage entity session RequestProcessType processType = this->m_esm->RequestProcess(p, m_serializer->GetEntityName(payload), (long)hdl.lock().get()); switch (processType) { case Chromium::PROCESS_NOTHING: DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do PROCESS_NOTHING"); return; case Chromium::PROCESS_SEND: //DbgEx("do PROCESS_SEND"); if (nullptr != p) WriteToFramework(p); break; case Chromium::PROCESS_STARTSESSION: { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do PROCESS_STARTSESSION"); auto entityName = m_serializer->GetEntityName(payload); if (entityName == "Chromium") { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("discard, don't make session with chromium"); break; } updateMsgPool(entityName, payload, hdl); do_sendJsonStartSession(entityName, m_serializer->GetClassName(payload)); } break; case Chromium::PROCESS_FINDSESSION: { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do PROCESS_FINDSESSION"); std::string js = m_esm->GetStartSessionAck(p, m_serializer->GetEntityName(payload)); js = restroreTransId(js); do_send_msg(hdl, js); } break; case Chromium::PROCESS_RECORDMSG: { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do PROCESS_RECORDMSG"); auto entityName = m_serializer->GetEntityName(payload); updateMsgPool(entityName, payload, hdl); } break; default: break; } } void CWebsocketServer::message_handler_ws_sm2(websocketpp::connection_hdl hdl, server::message_ptr msg) { long curHdl = (long)hdl.lock().get(); std::string payload = msg->get_payload(); #if (defined _WIN32 || defined _WIN64) payload = utf8_to_string(payload);//windows web utf8, terminal gbk #endif std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); if (nullptr == pJson.get()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> message_handler_ws_sm2, jsonErr:%s", payload.c_str()); return; } switch (m_ws_sm2_hdls_manager[curHdl]->getState()) { case SM2ProtocolState::WAIT_KEY_EXCHANGE: { auto pubKey = json_deal::getStringFromCjsonObj(pJson.get(), "pubKey"); if (pubKey.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("pubKey == null"); return; } m_ws_sm2_hdls_manager[curHdl]->setOpposite(pubKey.second.GetData()); auto encPub = m_ws_sm2_hdls_manager[curHdl]->GenerateEncPubKey(); if (!encPub.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> message_handler_ws_sm2 err:%s", encPub.second.c_str()); break; } std::string js = CSimpleString::Format("{\"encPub\":\"%s\"}", encPub.second.c_str()).GetData(); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> message_handler_ws_sm2 send js:%s", js.c_str()); do_send_msg(hdl, js); m_ws_sm2_hdls_manager[curHdl]->setState(SM2ProtocolState::DATA_EXCHANGE); } break; case SM2ProtocolState::DATA_EXCHANGE: { auto sign = json_deal::getStringFromCjsonObj(pJson.get(), "sign"); if (sign.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("sign == null"); return; } auto msgData = json_deal::getStringFromCjsonObj(pJson.get(), "msg"); if (msgData.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("msgData == null"); return; } auto decMsg = m_ws_sm2_hdls_manager[curHdl]->DecryptMsg(sign.second.GetData(), msgData.second.GetData()); if(decMsg.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("DecryptMsg err:%s", decMsg.second.c_str()); return; } msg->set_payload(decMsg.second); message_handler(hdl, msg); } break; default: return; } } // websocket message handler void CWebsocketServer::message_handler(websocketpp::connection_hdl hdl, server::message_ptr msg) { /* static bool isTest = true; if (isTest) { msg->set_payload("{\"messageType\":13,\"transID\" : 11111,\"name\" : \"UIState\",\"value\" : \"M\"}"); isTest = false; } else return; */ static int pos = 0; static std::map t_hdlArr; int hdlPos = (long)hdl.lock().get(); if (t_hdlArr.end() == t_hdlArr.find(hdlPos)) t_hdlArr[hdlPos] = pos++; auto msgHandleFun = [&]() { //DbgEx("CWebsocketServer -> message_handler"); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); std::string payload = msg->get_payload(); // proto convert here #if (defined _WIN32 || defined _WIN64) payload = utf8_to_string(payload);//windows web utf8, terminal gbk #endif std::shared_ptr pJson(cJSON_Parse(payload.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); if (nullptr == pJson.get()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> message_handler, jsonErr:%s", payload.c_str()); return; } auto transIdJson = cJSON_GetObjectItem(pJson.get(), "transId");//不做相关改造,因为这里还使用了set if (transIdJson != nullptr) { int transid = transIdJson->valueint; int modifyT = t_hdlArr[hdlPos] << 24; int dstTransId = transid ^ modifyT; cJSON_SetIntValue(transIdJson, dstTransId); } auto messageTypeJson = json_deal::getIntergerFromCjsonObj(pJson.get(), "messageType"); if (messageTypeJson.first == false) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> messageTypeJson == null"); return; } char *unformateStr = cJSON_PrintUnformatted(pJson.get()); std::string dstPayLoad = unformateStr; delete[]unformateStr; auto messageType = messageTypeJson.second; if (messageType < WEB_CHROMIUM_MSG_BEGIN) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("deal_msg, messageType:%d(%s), len:%d, payload:%s", messageType, GetMessageTypeString(messageType).c_str(), payload.length(), payload.length() > 800 ? payload.substr(0, 800).append("...").c_str() : payload.c_str()); deal_msg(dstPayLoad, hdl); } else if (messageType > WEB_CHROMIUM_MSG_BEGIN && messageType < WEB_CHROMIUM_MSG_END) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("deal_webchromium_msg, messageType:%d(%s), len:%d, payload:%s", messageType, GetMessageTypeString(messageType).c_str(), payload.length(), payload.length() > 800 ? payload.substr(0, 800).append("...").c_str() : payload.c_str()); deal_webchromium_msg(dstPayLoad, hdl, messageType); } else if (messageType > METHOD_SYSTEM_START && messageType < METHOD_SYSTEM_END) deal_logMsg(dstPayLoad, hdl, messageType); else if (messageType == METHOD_BEIDOU_LOG) deal_logMsg(dstPayLoad, hdl, messageType); }; boost::thread dealMsgThread(msgHandleFun); dealMsgThread.join(); } std::string CWebsocketServer::restroreTransId(std::string payLoad) { std::shared_ptr pJson(cJSON_Parse(payLoad.c_str()), [](cJSON* p) { if (nullptr != p) cJSON_Delete(p); }); auto transIdJson = cJSON_GetObjectItem(pJson.get(), "transId");//不改动,因为需要set if (transIdJson != nullptr) { int transid = transIdJson->valueint; int dstTransId = transid & 0x00FFFFFF; cJSON_SetIntValue(transIdJson, dstTransId); } char* unformateStr = cJSON_PrintUnformatted(pJson.get()); std::string dstPayLoad = unformateStr; delete[]unformateStr; return dstPayLoad; } void CWebsocketServer::open_handler(websocketpp::connection_hdl hdl) { // hand shake here server::connection_ptr con = m_wsserver.get_con_from_hdl(hdl); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("new ws connection to ws server : %u, isSecure:%d, url:%s", hdl.lock().get(), con->get_uri()->get_secure(), con->get_uri()->str().c_str()); m_connection_hdls.insert(std::pair((long)hdl.lock().get(), hdl)); } void CWebsocketServer::open_handler_wss(websocketpp::connection_hdl hdl) { // hand shake here auto con = m_server_wss.get_con_from_hdl(hdl); unsigned int dstHdl = (long)hdl.lock().get();//start from 0, be different from ws DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("new wss connection to ws server : %u, isSecure:%d, url:%s", dstHdl, con->get_uri()->get_secure(), con->get_uri()->str().c_str()); m_connection_wss_hdls.insert(std::pair((long)dstHdl, hdl)); } void CWebsocketServer::open_handler_ws_sm2(websocketpp::connection_hdl hdl) { // hand shake here auto con = m_ws_sm2_server.get_con_from_hdl(hdl); unsigned int dstHdl = (long)hdl.lock().get();//start from 0, be different from ws DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("new ws by encrypt connection to ws server : %u, isSecure:%d, url:%s", dstHdl, con->get_uri()->get_secure(), con->get_uri()->str().c_str()); m_connection_ws_sm2_hdls.insert(std::pair(dstHdl, hdl)); m_ws_sm2_hdls_manager.insert(std::make_pair(dstHdl, new SM2_Encrypt_Manager())); } void CWebsocketServer::close_handler(websocketpp::connection_hdl hdl) { // hand shake here auto connectionIter = m_connection_hdls.find((long)hdl.lock().get()); if (m_connection_hdls.end() != connectionIter) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws connection with ws server closed : %u", hdl.lock().get()); m_connection_hdls.erase(connectionIter); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws connection close erase failed : %u", hdl.lock().get()); } void CWebsocketServer::close_handler_wss(websocketpp::connection_hdl hdl) { // hand shake here auto connectionIter = m_connection_wss_hdls.find((long)hdl.lock().get()); if (m_connection_wss_hdls.end() != connectionIter) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("wss connection with ws server closed : %u", hdl.lock().get()); m_connection_wss_hdls.erase(connectionIter); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("wss connection close erase failed : %u", hdl.lock().get()); } void CWebsocketServer::close_handler_ws_sm2(websocketpp::connection_hdl hdl) { // hand shake here auto connectionIter = m_connection_ws_sm2_hdls.find((long)hdl.lock().get()); if (m_connection_ws_sm2_hdls.end() != connectionIter) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws sm2 connection with ws server closed : %u", hdl.lock().get()); m_connection_ws_sm2_hdls.erase(connectionIter); m_ws_sm2_hdls_manager.erase((long)hdl.lock().get()); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws sm2 connection close erase failed : %u", hdl.lock().get()); } void CWebsocketServer::do_run() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); // Start the Asio io_service run loop DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> do_run, Start the Asio io_service run loop"); while (!boost::this_thread::interruption_requested()) { try { m_ios.poll(); Sleep(2); } catch (const std::exception& e) { // 输出标准异常信息 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Exception in ios poll: %s", e.what()); } catch (...) { // 输出其他异常信息 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Other exception in ios poll"); } } } void CWebsocketServer::do_relink() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do_relink Enter"); auto checkEntityIsNoStart = [&](std::string entityName) -> bool { CSmartPointer spFunc = m_pEntity->GetFunction(); LOG_ASSERT(spFunc != NULL); CEntityStaticInfo StaticInfo; CEntityRunInfo RunInfo; do { if (Error_Succeed != spFunc->GetEntityStaticInfo(entityName.c_str(), StaticInfo)) break; if (Error_Succeed != spFunc->GetEntityRunInfo(entityName.c_str(), RunInfo)) break; return RunInfo.eState == EntityState_NoStart; } while (false); return true; }; while (!boost::this_thread::interruption_requested()) { try { boost::this_thread::sleep_for(boost::chrono::seconds(10)); if (boost::this_thread::interruption_requested()) break; auto unlinkArr = m_esm->queryUnLinkSession(); boost::lock_guard lock(m_dealMsgLock); std::string breakEntityStr = ""; std::string noStartEntity = ""; std::string noServerEntity = ""; #if (defined _WIN32 || defined _WIN64) for each (auto it in unlinkArr) #else for (auto it : unlinkArr) #endif { if (checkEntityIsNoStart(it)) { if (noStartEntity.empty()) noStartEntity.append(it); else noStartEntity.append("|").append(it); continue; } if (!CWSCodec::getInstance()->checkEntityHasService(it)) { if (noServerEntity.empty()) noServerEntity.append(it); else noServerEntity.append("|").append(it); continue; } auto ret = getEntityClass(it); if (ret.first) { if (breakEntityStr.empty()) breakEntityStr.append(it); else breakEntityStr.append("|").append(it); do_sendJsonStartSession(it, ret.second); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("unable find class of entity %s", it.c_str()); } if (!breakEntityStr.empty()) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("try to relink entity : %s, noStartEntity: %s, noServerEntity: %s", breakEntityStr.c_str(), noStartEntity.c_str(), noServerEntity.c_str()); } catch (...) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("exception in do_relink"); } } } void CWebsocketServer::run() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CWebsocketServer -> run"); m_doRunThread = boost::thread(boost::bind(&CWebsocketServer::do_run, this)); m_doReLinkThread = boost::thread(boost::bind(&CWebsocketServer::do_relink, this)); } template bool CWebsocketServer::sendBroadCast(T &connections, Y &senders, std::string msg) { for (auto it = connections.begin(); it != connections.end(); it++) { try { websocketpp::connection_hdl hdl = it->second; websocketpp::lib::error_code dstExption; senders.send(hdl, msg, websocketpp::frame::opcode::TEXT, dstExption); } catch (const websocketpp::lib::error_code& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("senders send crash : error message=%s", e.message()); return false; } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("std exception : %s", e.what()); return false; } catch (...) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("other exception"); return false; } } return true; } void CWebsocketServer::do_sendJsonBroadcast(std::string js) { js = restroreTransId(js); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message broadcast : json = %s", js.c_str()); if (js.empty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("string empty"); return; } auto formatMapToString = [](const std::map& mapArr) -> std::string { std::stringstream ss; ss << "["; for (auto it : mapArr) ss << "(" << it.first << ", " << (long)it.second.lock().get() << ")"; ss << "]"; return ss.str(); }; if (!sendBroadCast(m_connection_hdls, m_wsserver, js)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws server broadcast error"); } if (!sendBroadCast(m_connection_ws_sm2_hdls, m_ws_sm2_server, js)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws_sm2 server broadcast error"); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("do_sendJsonBroadcast: broadcasts have already send to these terminals, no_security:%s, security:%s", formatMapToString(m_connection_hdls).c_str(), formatMapToString(m_connection_ws_sm2_hdls).c_str()); /* if (!sendBroadCast(m_connection_wss_hdls, m_server_wss, js)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("wss server broadcast error"); } */ } void CWebsocketServer::do_send_msg(int hdl, std::string msg) { //send ws try { std::map::iterator it = m_connection_hdls.find(hdl); if (m_connection_hdls.end() != it) { do_send_msg(it->second, msg); return; } } catch (const websocketpp::lib::error_code& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws send crash : error message=%s", e.message()); } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws send std exception : %s", e.what()); } catch (...) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws send other exception"); } //send ws sm2 try { std::map::iterator it = m_connection_ws_sm2_hdls.find(hdl); if (m_connection_ws_sm2_hdls.end() != it) { //DbgEx("Send...."); do_send_msg(it->second, msg); } return; } catch (const websocketpp::exception& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws sm2 send crash : error message=%s", e.what()); } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws sm2 send std exception : %s", e.what()); } catch (...) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ws sm2 send other exception"); } //send wss /* try { //DbgEx("do_send_notifyMsg Enter..."); std::map::iterator it = m_connection_hdls.find(hdlID); if (m_connection_hdls.end() != it) { //DbgEx("Send...."); websocketpp::connection_hdl hdl = it->second; websocketpp::lib::error_code dstExption; m_wsserver.send(hdl, notifyMsg.GetData(), websocketpp::frame::opcode::TEXT, dstExption); } //DbgEx("do_send_notifyMsg End..."); } catch (const websocketpp::lib::error_code& e) { DbgEx("m_wsserver send crash : error message=%s", e.message()); } catch (const std::exception& e) { DbgEx("std exception : %s", e.what()); } catch (...) { DbgEx("other exception"); } */ return; } void CWebsocketServer::do_send_msg(websocketpp::connection_hdl hdl, std::string msg) { unsigned int dstHdl = (long)hdl.lock().get(); websocketpp::lib::error_code dstExption; if (m_connection_hdls.find(dstHdl) != m_connection_hdls.end()) { m_wsserver.send(hdl, msg, websocketpp::frame::opcode::TEXT, dstExption); } else if (m_connection_ws_sm2_hdls.find(dstHdl) != m_connection_ws_sm2_hdls.end()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("dstHdl:%d, save:%d", dstHdl, m_connection_ws_sm2_hdls[dstHdl].lock().get()); if(m_ws_sm2_hdls_manager[dstHdl]->getState() == SM2ProtocolState::WAIT_KEY_EXCHANGE) m_ws_sm2_server.send(m_connection_ws_sm2_hdls[dstHdl], msg, websocketpp::frame::opcode::TEXT, dstExption); else { auto dst = m_ws_sm2_hdls_manager[dstHdl]->EncryptMsg(msg); std::string js = CSimpleString::Format("{\"sign\":\"%s\",\"msg\":\"%s\"}", dst.first.c_str(), dst.second.c_str()).GetData(); m_ws_sm2_server.send(m_connection_ws_sm2_hdls[dstHdl], js, websocketpp::frame::opcode::TEXT, dstExption); } } /* else m_server_wss.send(hdl, msg, websocketpp::frame::opcode::TEXT, dstExption); */ } void CWebsocketServer::do_send_notifyMsg(unsigned hdlID, unsigned transId, const std::string& reason, const std::string& errmsg, const std::string& rebootTime, const DWORD& dwSysError, const DWORD& dwUserCode) { #if (defined _WIN32 || defined _WIN64) auto notifyMsg = CSimpleStringA::Format("{\"messageType\":%d,\"transID:%d\", \"reason\":%s, \"errmsg\":%s, \"rebootTime\":%s}", RegisterNotify, transId, reason, errmsg, rebootTime); #else auto notifyMsg = CSimpleStringA::Format(R"({"messageType":%d,"transID:%d", "reason":%s, "errmsg":%s, "rebootTime":%s})", RegisterNotify, transId, reason, errmsg, rebootTime); #endif do_send_msg(hdlID, notifyMsg.GetData()); } void CWebsocketServer::do_sendJson(std::string js, int messageType, int hdlID, unsigned int id) { js = restroreTransId(js); if(g_withLinkLog) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("WebSocket Search message_from_socket : json = %s", js.c_str()); else if(messageType != MessageType::RequestAck && messageType != MessageType::Event)//do not upload message which messageType equals to RequestAck or Event DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("WebSocket Search message_from_socket : json = %s", js.c_str()); if (js.empty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("string empty"); return; } if (m_connection_hdls.empty() && m_connection_ws_sm2_hdls.empty()) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message_from_socket : no websocket client connection"); else { #if(defined _WIN32 || defined _WIN64) js = string_to_utf8(js); #endif if (js.empty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("string empty 2"); return; } do_send_msg(hdlID, js); } } // socket message handler void CWebsocketServer::message_from_socket(CMessage& msg, unsigned int id) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); // get message from socket and deserialize // then send back to the web client auto bufferLength = msg.getBufferLength(); /* if (bufferLength > MAX_TRANSFER_LEN) DbgEx("WebSocket Search message_from_socket : buffer len = %d, buffer pre50:%s", msg.getBufferLength(), msg.printfHEX(50).c_str()); else receivehexdump(msg.getPayload(), msg.getLength()); */ //else // DbgEx("WebSocket Search message_from_socket : buffer len = %d", msg.getBufferLength()); int replaceTransId = 0; if (msg.getLength() > 16 && m_esm != NULL) {//this is return buffer, it would not send out again, so I exchange the transId and sessionId place msg.exchangeSessionIdAndTransId(); auto tmpReplace = m_esm->getSrcTransID(msg.getTransID()); replaceTransId = tmpReplace.first == true ? tmpReplace.second : 0; } // 处理session ack,获取hdlID unsigned int hdlID = 0; std::vector> sendArr; if (MessageType::Event == msg.getMessageType()) { auto formatVectorToString = [](const std::vector>& vec) -> std::string { std::stringstream ss; ss << "["; for (size_t i = 0; i < vec.size(); ++i) { ss << "(" << vec[i].first << ", " << vec[i].second << ")"; if (i != vec.size() - 1) { ss << ", "; } } ss << "]"; return ss.str(); }; m_esm->AskProcessEvent(&msg, sendArr); if (sendArr.size() == 0) m_esm->AskProcessEvent(&msg, sendArr); std::string unaccurate_js; for (auto i = sendArr.begin(); i != sendArr.end(); i++) { msg.setTransID(i->first); std::string js = this->m_serializer->BufferToJson(msg, boost::bind(&EntitySessionManager::doWithErrorCode, m_esm, _1, _2), 0); do_sendJson(js, msg.getMessageType(), i->second, id); unaccurate_js = js; } auto signatureID = msg.getSignatureID(); if (sendArr.size() == 0) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message_from_socket event sendArr.size() == 0"); else if (signatureID != eMsgSig_LogInfo && signatureID != eMsgSig_EntityStatus && signatureID != eMsgSig_PerformanceList)//fiter guiconsole msg { #ifdef DEVOPS_ON_ST /*DevOps流水线编译,ST环境*/ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message_from_socket event %s send to arr:%s" , unaccurate_js.c_str(), formatVectorToString(sendArr).c_str()); #elif defined(DEVOPS_ON_UAT)/*DevOps流水线编译,UAT环境*/ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message_from_socket event %s send to arr:%s" , unaccurate_js.c_str(), formatVectorToString(sendArr).c_str()); #else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("message_from_socket event send to arr:%s", formatVectorToString(sendArr).c_str()); #endif } } else if (MessageType::EndSession == msg.getMessageType()) //session end { int sessionId = msg.getTransID(); auto ret = m_esm->DoSessionRemove(sessionId); if (ret.first) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("MessgeType:%s, detect session %s:%d lost!remove success", GetMessageTypeString(2).c_str(), ret.second.c_str(), sessionId); else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("MessgeType:%s, detect session %d lost!remove failed", GetMessageTypeString(2).c_str(), sessionId); } else if (MessageType::SessionAck == msg.getMessageType()) {//sessionAck auto ret = m_esm->AskProcessSession(&msg, hdlID); auto sessionId = msg.getSessionID(); if (ACKPROCESS_NOTHING == ret.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("MessgeType:%s, can not find save session, process noting, %s", GetMessageTypeString(2).c_str(), ret.second.c_str());//error return; } if (0 != hdlID) {//hdlId为0时,说明本地发起的session std::string js = this->m_serializer->BufferToJson(msg, boost::bind(&EntitySessionManager::doWithErrorCode, m_esm, _1, _2), replaceTransId); do_sendJson(js, msg.getMessageType(), hdlID, id); //发给首记录的CMessage } for (auto cur = m_msg_pool.begin(); cur != m_msg_pool.end(); cur++) {//sessionId为-1时需处理,否则会引发消息风暴 if (cur->first == ret.second) { std::vector> msgArr(cur->second); m_msg_pool.erase(cur); //为防止处理消息时引发消息风暴,拷贝并删除原msg_pool if (-1 != sessionId) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Session with %s Make, deal with record Msg:%d", ret.second.c_str(), msgArr.size()); for (auto msg = msgArr.begin(); msg != msgArr.end(); msg++) deal_msg(msg->second, msg->first); break; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Session with %s Make Failed, deal with record Msg:%d", ret.second.c_str(), msgArr.size()); #if (defined _WIN32 || defined _WIN64) for each (auto msg in msgArr) #else for (auto msg : msgArr) #endif deal_sessionBreakMsg(msg.second, msg.first); break; } } } } else { m_esm->AckProcess(&msg, hdlID); //替换真实的transId,update session map std::string js = this->m_serializer->BufferToJson(msg, boost::bind(&EntitySessionManager::doWithErrorCode, m_esm, _1, _2), replaceTransId); do_sendJson(js, msg.getMessageType(), hdlID, id); } } std::string get_password() { return "test"; } // See https://wiki.mozilla.org/Security/Server_Side_TLS for more details about // the TLS modes. The code below demonstrates how to implement both the modern enum tls_mode { MOZILLA_INTERMEDIATE = 1, MOZILLA_MODERN = 2 }; const char* certificate_content = "-----BEGIN CERTIFICATE-----\n" "MIICtDCCAZygAwIBAgIUbdvfhsKgSv4zdyF1Y8OjFOFiCiMwDQYJKoZIhvcNAQEL\n" "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDEyOTAyMDIyNloXDTI1MDEy\n" "ODAyMDIyNlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\n" "AAOCAQ8AMIIBCgKCAQEAr+2L/iVAFrtMsqMFaI6UgTLhxZCAPkH6LsQMMYOzMz77\n" "pRhOKv0RzNu4zSAt14/U29R8deYa/244XNyHgj2TniFotxR1J3Q0Kzaf22g4WqIR\n" "qZKJ8y1ry4g70zgyPHUNmcmxrXvq1Y4k8J/g3Jqhlqqcw1+Sy8xQZy+oXhTsjh2+\n" "TGeVG9l2m5jdyWJSw7jE9rT0iJhXiuaTXQ8osjsspdvPhIg5agKvP2T6JpG/8jLY\n" "4Kkvz38lNiRwahmaet7pU9ggtHyXR0vUGN7M9Z14c17v2veuBwbNDLWeGSTaFA8b\n" "M9BOntzMhM6tItZvf2TGR+TAIkGPLcdCpXoW7PFlZQIDAQABMA0GCSqGSIb3DQEB\n" "CwUAA4IBAQA6V3yl+Zdpimyi/bNeOwnC9Ml2yDzapsQBDiXlG97zj++bT/lwPvlV\n" "/Oti2EWrVCO59eaarQmdOBAfgpipJlxzsWGeya26D04MHGwMI5aejpLIlyETyMzf\n" "VzTIufMTtG3w37CSqUIyodhH4VhHGWPazQg3QKHiPryL0k2q9013mc8glSNLI//4\n" "tOk5ZRzHbb8uLmgGp54Cr4449DwtltAwQ74Y+NY/0Fasu7jvjLXm4o37twfPGiAy\n" "LRjbBuEV6/ab8dTmOQA6mPvNOGHqJg40Y6d3XCiQ0H2ovqBvMz+83tFrmRwcydKP\n" "mi9O1t8a62FV2WI38+gIleRJ/iNkpZhI\n" "-----END CERTIFICATE-----"; const char* dh_content = "-----BEGIN DH PARAMETERS-----\n" "MIIBCAKCAQEAzg8TpgTyX/im9EqTq1tD1fx1IoxE/u6CwE+tXbHL58KRrJStOiGw\n" "TyZwqOKIqgC0wbJztjpMYq+X8cfDzkOE7GoSaqYAB5r9AafUiIV6cpvJ+ilWRxZK\n" "wo2Qjydz9F+xGcIXnQf/vSpK5Hws9h9OpnyCz413i4PDQXzQnKyHOTCq4t7UEU4m\n" "oZ9Weum8zGHomBFubyuinBkIyZYRg4NPnqirTgChfLVpbME9menEWGF4YPtEc3WC\n" "AIXtUfKLgAIF/2MNaiTzmm6JCcrfof1PED6VackHimHUwwV/miW50MfnlIery4g8\n" "B72avGZXhTQ+49qDaPPfLqlvhQ6MOxc0BwIBAg==\n" "-----END DH PARAMETERS-----"; const char* private_key_content = "-----BEGIN RSA PRIVATE KEY-----\n" "MIIEpAIBAAKCAQEAr+2L/iVAFrtMsqMFaI6UgTLhxZCAPkH6LsQMMYOzMz77pRhO\n" "Kv0RzNu4zSAt14/U29R8deYa/244XNyHgj2TniFotxR1J3Q0Kzaf22g4WqIRqZKJ\n" "8y1ry4g70zgyPHUNmcmxrXvq1Y4k8J/g3Jqhlqqcw1+Sy8xQZy+oXhTsjh2+TGeV\n" "G9l2m5jdyWJSw7jE9rT0iJhXiuaTXQ8osjsspdvPhIg5agKvP2T6JpG/8jLY4Kkv\n" "z38lNiRwahmaet7pU9ggtHyXR0vUGN7M9Z14c17v2veuBwbNDLWeGSTaFA8bM9BO\n" "ntzMhM6tItZvf2TGR+TAIkGPLcdCpXoW7PFlZQIDAQABAoIBAAMiJLpp0O6mttq+\n" "pw/B7Fixvo4tgO867xkKoln2achpoIND/85ps/m1VyEGJ/LdK7IfonjaGJSAks3q\n" "mppB/QFVwH70RRLnEa/MWQQIIurQVKazxrO3VSJqooAkUda8UfnxevHnUVss3TEQ\n" "8+kR8vtTPhgHuX5aPPtdgK7uSflM/DnBMQUW2y9t85ahAosRLfRO1LPsKC+cSmGY\n" "tELVnBgtKE64Am5rkRododcEkLVrQkf4jenqL0yusuwjSFUK1AUhOOS0Pp47oKCC\n" "gXo4oBWmM7Zyj9+/OCkJ4HVBzCERGx5/DJEFRd9KF2HRpOG4cWH5u0c7Ab6WzIul\n" "w6JM2JkCgYEA6E8gdZTueoK1RteyZgosJWA5aBrDSK8PQvykh1XgWdsBoD6wdDV6\n" "xEpwX+VL0YaVLMaxxqqMMOx9x2ONK/wa11osrOTLqs+yzSqFK2RerpGpm/bbPVg4\n" "mCVC9CBHN40TSVLLCrdlcaJvDXLsVNJR1Qc7UPoLf5ZwnEBzMnaYj/0CgYEAwd57\n" "UM/sZ6pSgZkBh0XdU/r6UAGE+5wUSVQPpOqOfRXp7KCEO1LoMaWs1xVEBHcjI4Zm\n" "oXYTT8XXN2Y8fxeYk5oabDTEUU3RiEySxDmMzJAdGIhSGlAmHnob+pjpnNrSU+ml\n" "ktf8EQPT4Uh/9vTwfJfC39cqRyrgMDGHWgDL44kCgYEAnYT5x4DC68MxU+XyC4qe\n" "QIGsq1BqViCNwqg4j6PFSmhcA+I+F64jnnGzHPMHo/0TrZbU+JawFIRnDQoNsWNy\n" "d8+nN1y0VRAcd017mt6l7MzMKvsJ0eC+DzxE1/ADGkHIcBF5p7yPRqwTjRT99s3d\n" "uwr6R4Akx9Ckbu6sre0IqakCgYEAur7tuG1hAoadjTrurvhMd63l2pVsHNY+8Fep\n" "7ikG8lTejVIdretxwQkfEdvpNgfw8DJxwAw2E/y2ECZKFf6LuXqTAzJc/RhhwtJH\n" "+f6Zsx8K9+uwcqpL3cWwF9eeCLr8KVqCZI3qwBUYzwSAR0mwMcQaMnZXwk/5vlKn\n" "V7o2rEkCgYBfQyd4bdSPNkVayTEBK2L8jG4VuXGYuqdBtaHtNrrvAUsQEhv6RFv9\n" "b3g6xZrHI2WZ2yoR2xPJ8kuQLmTB04eg/VuVn50N/rdeZyKkmpb9k1fZftQ/2dDE\n" "kgJQP3/xqeULzdKboekyUsM0uT5/jbVPaelVtOIpqfcdtLtQc6/4eQ==\n" "-----END RSA PRIVATE KEY-----"; context_ptr on_tls_init(tls_mode mode, websocketpp::connection_hdl hdl) { namespace asio = websocketpp::lib::asio; std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl; std::cout << "using TLS mode: " << (mode == MOZILLA_MODERN ? "Mozilla Modern" : "Mozilla Intermediate") << std::endl; context_ptr ctx = websocketpp::lib::make_shared(asio::ssl::context::sslv23); try { if (mode == MOZILLA_MODERN) { // Modern disables TLSv1 ctx->set_options(asio::ssl::context::default_workarounds | asio::ssl::context::no_sslv2 | asio::ssl::context::no_sslv3 | asio::ssl::context::no_tlsv1 | asio::ssl::context::single_dh_use); } else { ctx->set_options(asio::ssl::context::default_workarounds | asio::ssl::context::no_sslv2 | asio::ssl::context::no_sslv3 | asio::ssl::context::single_dh_use); } ctx->set_password_callback(bind(&get_password)); ctx->use_certificate_chain(asio::buffer(certificate_content, std::strlen(certificate_content))); ctx->use_private_key(asio::buffer(private_key_content, std::strlen(private_key_content)), asio::ssl::context::pem); // Example method of generating this file: // `openssl dhparam -out dh.pem 2048` // Mozilla Intermediate suggests 1024 as the minimum size to use // Mozilla Modern suggests 2048 as the minimum size to use. ctx->use_tmp_dh(asio::buffer(dh_content, std::strlen(dh_content))); std::string ciphers; if (mode == MOZILLA_MODERN) { ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"; } else { ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; } if (SSL_CTX_set_cipher_list(ctx->native_handle(), ciphers.c_str()) != 1) { std::cout << "Error setting cipher list" << std::endl; } } catch (std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; } return ctx; } void CWebsocketServer::init_websocket() { auto checkPortExist = []() -> bool { boost::asio::io_service ioService; boost::asio::ip::tcp::socket* pSockTcp = NULL; bool bSockUseError = false; try { auto tcpEndpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), DEFAULT_SERVER_PORT); pSockTcp = new boost::asio::ip::tcp::socket(ioService, tcpEndpoint); bSockUseError = false; } catch (...) { bSockUseError = true; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("%s sock %d error", __FUNCTION__, DEFAULT_SERVER_PORT); } //释放 if (!bSockUseError && pSockTcp != NULL) { delete pSockTcp; pSockTcp = NULL; } ioService.stop(); return bSockUseError; }; /* while (true) { if (!checkPortExist()) break; else DbgEx("checkPortExist failed"); std::this_thread::sleep_for(std::chrono::seconds(5)); } */ try { //ws // Set logging settings m_wsserver.set_error_channels(websocketpp::log::elevel::all); m_wsserver.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("m_wsserver.get_max_message_size = %d", m_wsserver.get_max_message_size()); m_wsserver.set_max_message_size(MAX_TRANSFER_LEN); m_wsserver.set_close_handshake_timeout(3000); m_wsserver.set_pong_timeout(3000); // Initialize Asio m_wsserver.init_asio(&m_ios); // Set the default message handler to the echo handler DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Set the default message handler to the echo handler"); m_wsserver.set_message_handler(websocketpp::lib::bind(&CWebsocketServer::message_handler, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Set set_open_handler"); m_wsserver.set_open_handler(websocketpp::lib::bind(&CWebsocketServer::open_handler, this, websocketpp::lib::placeholders::_1)); m_wsserver.set_close_handler(websocketpp::lib::bind(&CWebsocketServer::close_handler, this, websocketpp::lib::placeholders::_1)); // Listen on port 9002, add m_acceptor->set_option(lib::asio::socket_base::reuse_address(true), bec); m_wsserver.listen(DEFAULT_SERVER_PORT); // Queues a connection accept operation DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Queues a connection accept operation"); m_wsserver.start_accept(); //ws sm2 // Set logging settings m_ws_sm2_server.set_error_channels(websocketpp::log::elevel::all); m_ws_sm2_server.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("m_ws_sm2_server.get_max_message_size = %d", m_ws_sm2_server.get_max_message_size()); m_ws_sm2_server.set_max_message_size(MAX_TRANSFER_LEN); m_ws_sm2_server.set_close_handshake_timeout(3000); m_ws_sm2_server.set_pong_timeout(3000); // Initialize Asio m_ws_sm2_server.init_asio(&m_ios); // Set the default message handler to the echo handler m_ws_sm2_server.set_message_handler(websocketpp::lib::bind(&CWebsocketServer::message_handler_ws_sm2, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); m_ws_sm2_server.set_open_handler(websocketpp::lib::bind(&CWebsocketServer::open_handler_ws_sm2, this, websocketpp::lib::placeholders::_1)); m_ws_sm2_server.set_close_handler(websocketpp::lib::bind(&CWebsocketServer::close_handler_ws_sm2, this, websocketpp::lib::placeholders::_1)); // Listen on port 9003, add m_acceptor->set_option(lib::asio::socket_base::reuse_address(true), bec); m_ws_sm2_server.listen(DEFAULT_SERVER_WS_SM2_PORT); // Queues a connection accept operation DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Queues a connection accept operation"); m_ws_sm2_server.start_accept(); /* // wss m_server_wss.set_error_channels(websocketpp::log::elevel::all); m_server_wss.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("m_server_wss.get_max_message_size = %d", m_server_wss.get_max_message_size()); m_server_wss.set_max_message_size(MAX_TRANSFER_LEN); m_server_wss.set_close_handshake_timeout(3000); m_server_wss.set_pong_timeout(3000); // Initialize Asio m_server_wss.init_asio(&m_ios); // Set the default message handler to the echo handler DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Set the default message handler to the echo handler"); m_server_wss.set_message_handler(websocketpp::lib::bind(&CWebsocketServer::message_handler, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Set handles"); m_server_wss.set_open_handler(websocketpp::lib::bind(&CWebsocketServer::open_handler_wss, this, websocketpp::lib::placeholders::_1)); m_server_wss.set_close_handler(websocketpp::lib::bind(&CWebsocketServer::close_handler_wss, this, websocketpp::lib::placeholders::_1)); m_server_wss.set_tls_init_handler(bind(&on_tls_init, MOZILLA_INTERMEDIATE, websocketpp::lib::placeholders::_1)); // Listen on port 9002, add m_acceptor->set_option(lib::asio::socket_base::reuse_address(true), bec); m_server_wss.listen(DEFUALT_SERVER_WSS_PORT); // Queues a connection accept operation DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Queues a connection accept operation"); m_server_wss.start_accept(); */ m_initSuccess = true; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do_run end"); } catch (websocketpp::exception const& e) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("websocketpp exception %s ", e.what()); m_initSuccess = false; } catch (...) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("other exception"); m_initSuccess = false; } } void CWebsocketServer::myTest() { } #if(defined _WIN32 || defined _WIN64) std::string CWebsocketServer::utf8_to_string(const std::string& str) { int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0); wchar_t* wszGBK = new wchar_t[len + 1]; wmemset(wszGBK, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)str.c_str(), -1, wszGBK, len); len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); char* szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); std::string strTemp(szGBK); delete[] szGBK; delete[] wszGBK; return strTemp; } std::string CWebsocketServer::string_to_utf8(const std::string& str) { int wcLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0); if (wcLen > 0) { wchar_t* pwBuf = new wchar_t[wcLen + 1]; if (pwBuf == NULL) { return std::string(); } memset(pwBuf, 0, sizeof(wchar_t) * (wcLen + 1)); wcLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pwBuf, wcLen); if (wcLen <= 0) { delete[] pwBuf; return std::string(); } std::wstring modifyStr = pwBuf; if (modifyBySpecialStr(modifyStr)) { memset(pwBuf, 0, sizeof(wchar_t) * (wcLen + 1)); memcpy(pwBuf, modifyStr.c_str(), sizeof(wchar_t) * (modifyStr.length())); } int ucLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, 0, NULL, NULL); //DbgEx("ucLen = %d", ucLen); if (ucLen < 0) { delete[] pwBuf; return std::string(); } char* pBuf = new char[ucLen + 1]; if (pBuf == NULL) { delete []pwBuf; return std::string(); } memset(pBuf, 0, sizeof(char) * (ucLen + 1)); ucLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, pBuf, ucLen, NULL, NULL); if (ucLen <= 0) { delete[] pwBuf; delete[] pBuf; return std::string(); } std::string retStr(pBuf); //DbgEx("string_to_utf8 return: %s", retStr.c_str()); if (pwBuf) { delete[] pwBuf; pwBuf = NULL; } if (pBuf) { delete[] pBuf; pBuf = NULL; } return retStr; } return std::string(); } #endif void CWebsocketServer::init_entity_sessions() { return; } }