#include "StdAfx.h" #include "NetworkClient.h" #include "TransCodeToString.h" #include "../Logger/Logger.h" SINGLETON_IMPLEMENT(CNetworkClient) CNetworkClient::CNetworkClient(void) : m_AcdDevID(0), m_IsAcdConnected(false), m_acdRecvMsgFun(nullptr) { } CNetworkClient::~CNetworkClient(void) { } /***************************************************************** **【函数名称】 OnLinkStateChanged **【函数功能】 PDU连接状态变化事件处理(重载函数) **【参数】 **【返回值】 ****************************************************************/ void CNetworkClient::OnLinkStateChanged(const PduLinkContent& linkContent) { CString Msg; LOG_LEVEL Level = LOG_LEVEL_NORMAL; switch (linkContent.nLinkState) { case PDU_LINK_STATE_SUCCESSED: // 请求连接成功 Msg.Format(_T("{Net}: Far End[IP = %s, Port = %d], Hint = 网络连接成功..."), linkContent.szFarIp, linkContent.nFarPort); break; case PDU_LINK_STATE_FAILED: // 请求连接失败 Msg.Format(_T("{Net}: Far End[IP = %s, Port = %d], Hint = 网络连接失败..."), linkContent.szFarIp, linkContent.nFarPort); Level = LOG_LEVEL_ERROR; break; case PDU_LINK_STATE_ACCEPTED: // 已接受对端连接 Msg.Format(_T("{Net}: Far End[IP = %s, Port = %d], Hint = 已接受远端网络连接..."), linkContent.szFarIp, linkContent.nFarPort); break; case PDU_LINK_STATE_DISCONNECTED: // 连接已断开 { m_IsAcdConnected = false; m_IsCtiConnected = false; Msg.Format(_T("{Net}: Far End[Type=%d,IP = %s, Port = %d,AcdConnect=%d], Hint = 网络连接已断开..."), linkContent.nFarType, linkContent.szFarIp, linkContent.nFarPort, m_IsAcdConnected); Level = LOG_LEVEL_ERROR; } break; case PDU_LINK_STATE_REG_OK: // 注册成功 { Msg.Format(_T("{Net}:Far End[Type=%d,ID =%d,IP=%s,Port= %d]注册成功"), linkContent.nFarType, linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort); } break; case PDU_LINK_STATE_REG_FAILED: // 注册失败 Msg.Format(_T("{Net}: Far End[IP = %s, Port = %d], Hint = 网络连接注册失败, 通讯禁止..."), linkContent.szFarIp, linkContent.nFarPort); Level = LOG_LEVEL_ERROR; break; default: Msg.Format(_T("{Net}: Far End[Type = %d, ID = %d, IP = %s, Port = %d]"), linkContent.nFarType, linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort); break; } // end switch ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, Msg.GetBuffer(0)); Msg.ReleaseBuffer(); } /***************************************************************** **【函数名称】 OnRecvCommand **【函数功能】 接收具体命令并进行处理 **【参数】 **【返回值】 ****************************************************************/ void CNetworkClient::OnRecvCommand(CPduEntity* a_pPduEntity) { PDU_CMD_TYPE Type = a_pPduEntity->GetCmdType(); if (Type == PDU_CMD_LISTEN || PDU_CMD_REG == Type) return; else if (PDU_CMD_DEV_ONLINE_LIST == Type) { auto devList = a_pPduEntity->GetDataString(0); CString dev; dev.Format("|%d|", PDU_DEV_TYPE_CTI); auto newCtiConnected = devList.Find(dev) < 0 ? false : true; dev.Format("|%d|", PDU_DEV_TYPE_ACD); auto newAcdConnected = devList.Find(dev) < 0 ? false : true; bool isAutoConn = false; // cti,acd是否刚好两个都连接,达到条件可以自动签入 if (m_IsAcdConnected && !newAcdConnected) { // ACD 连接断开 m_IsAcdConnected = newAcdConnected; ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "[ACD]---连接断开"); } else if (!m_IsAcdConnected && newAcdConnected) { // ACD 连接 m_IsAcdConnected = newAcdConnected; ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[ACD]---已连接"); isAutoConn = newCtiConnected; } if (m_IsCtiConnected && !newCtiConnected) { // CTI 连接断开 m_IsCtiConnected = newCtiConnected; ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "[CTI]---连接断开"); } else if (!m_IsCtiConnected && newCtiConnected) { // CTI 连接 m_IsCtiConnected = newCtiConnected; ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[CTI]---已连接"); isAutoConn = m_IsAcdConnected; } if (isAutoConn && this->m_acdRecvMsgFun != nullptr) { this->m_acdRecvMsgFun(a_pPduEntity); } } else { CString strCMD = TransCodeToString(Type); CString strShow; strShow.Format("ACD->SERVER : 收到【 %s 】结果 即将转发至坐席", strCMD); ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_TRACE, strShow.GetBuffer(0)); if (this->m_acdRecvMsgFun != nullptr) { this->m_acdRecvMsgFun(a_pPduEntity); } } } /***************************************************************** **【函数名称】 init **【函数功能】 初始化 **【参数】 **【返回值】 ****************************************************************/ bool CNetworkClient::init(void) { // 初始化命令配置 auto pClient = CNetInterface::getNetInstance(); pClient->setLinkStateChanged(std::bind(&CNetworkClient::OnLinkStateChanged, this, std::placeholders::_1)); pClient->setRecvCommand(std::bind(&CNetworkClient::OnRecvCommand, this, std::placeholders::_1)); CString Ip = "127.0.0.1"; int Port = 8811; #ifdef ISUSEDYAMLCONFIG Ip.Format("%s", YamlConfig::GetInstance()->GetWsServerIP().c_str()); Port = YamlConfig::GetInstance()->GetWsServerPort(); #endif // !ISUSEDYAMLCONFIG if (!pClient->CreatePduClient(Ip, Port, PDU_DEV_TYPE_SERVER, 0, true)) { ::MessageBoxA(NULL, "Link To wsServer Failed", "ERROR", 0); ::SendMessageA(hwndd, WM_CLOSE, NULL, NULL); return false; } // end if ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "服务端与wsServer建立连接,注册中...."); return true; } /***************************************************************** **【函数名称】 release **【函数功能】 连接释放 **【参数】 **【返回值】 ****************************************************************/ void CNetworkClient::release(void) { CNetInterface::getNetInstance()->ClosePduClient(PDU_DEV_TYPE_SERVER, 0); } /***************************************************************** **【函数名称】 send2Cti **【函数功能】 发送PDU到CTI **【参数】 **【返回值】 ****************************************************************/ bool CNetworkClient::send2ACD(CPduEntity* a_pPduEntity) { BOOL bOk = CNetInterface::getNetInstance()->Send(a_pPduEntity, PDU_DEV_TYPE_ACD, m_AcdDevID); PDU_CMD_TYPE type = a_pPduEntity->GetCmdType(); CString strCMD = TransCodeToString(type); // char szCurrentDateTime[32]; // CTime nowtime; // nowtime = CTime::GetCurrentTime(); // // sprintf(szCurrentDateTime, "%4d-%.2d-%.2d %.2d:%.2d:%.2d", // nowtime.GetYear(), nowtime.GetMonth(), nowtime.GetDay(), // nowtime.GetHour(), nowtime.GetMinute(), nowtime.GetSecond()); int t_agent_id = a_pPduEntity->GetDataUInt(2); CString strShow; strShow.Format("SERVER->ACD [%d]: 向ACD发送【 %s 】命令,%d,Agent=%d", bOk, strCMD, m_AcdDevID, t_agent_id); ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, strShow.GetBuffer(0)); return bOk; }