| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- #include "StdAfx.h"
- #include "NetworkCti.h"
- #include "LineHolder.h"
- #include "IvrFlowHolder.h"
- #include "Logger.h"
- #include "MsgCenter.h"
- #include "Config.h"
- #include "CtiDataDef.h"
- #include "TaskMgr.h"
- SINGLETON_IMPLEMENT(CNetworkCti)
- CNetworkCti::CNetworkCti(void) : m_IsAcdConnected(FALSE), m_IsIvrConnected(FALSE)
- {
- }
- void CNetworkCti::__procRegDevListMsg(CPduEntity & a_PduEntity)
- {
- auto devList = a_PduEntity.GetDataString(0);
- CString dev;
- dev.Format("|%d|", PDU_DEV_TYPE_IVR);
- bool newIvrConnected = devList.Find(dev) < 0 ? false : true;
- dev.Format("|%d|", PDU_DEV_TYPE_ACD);
- auto newAcdConnected = devList.Find(dev) < 0 ? false : true;
- if (!m_IsAcdConnected && newAcdConnected) { // acd 连接
- m_IsAcdConnected = newAcdConnected;
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[ACD]---已连接");
- // 通知线路类Acd连接成功
- CLineHolder::GetInstance().onAcdConnected();
- }
- else if (m_IsAcdConnected && !newAcdConnected) { // acd连接断开
- m_IsAcdConnected = newAcdConnected;
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "[ACD]---连接断开");
- }
- if (m_IsIvrConnected && !newIvrConnected) { // ivr掉线
- m_IsIvrConnected = newIvrConnected;
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "[IVR]---连接断开");
- // 通知IvrFlow IVR连接断开
- CIvrFlowHolder::GetInstance().onIvrDisconnect();
- }
- else if (!m_IsIvrConnected && newIvrConnected) { // ivr上线
- m_IsIvrConnected = newIvrConnected;
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[IVR]---已连接");
- }
- }
- CNetworkCti::~CNetworkCti(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __procRegMsg
- **【函数功能】 处理注册命令
- **【参数】 a_PduEntity:注册命令
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__procRegMsg(CPduEntity& a_PduEntity)
- {
- bool RegResult = false;
- switch (a_PduEntity.GetLocalDevType())
- {
- case PDU_DEV_TYPE_ACD:
- RegResult = m_DevAcd.DevId == -1 ? true : false;
- break;
- case PDU_DEV_TYPE_IVR:
- RegResult = m_DevIvr.DevId == -1 ? true : false;
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- // 发送注册结果
- a_PduEntity.SetToExecReturn();
- a_PduEntity.SetDataBool(0, RegResult);
- CNetInterface::getNetInstance()->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
- }
- /*****************************************************************
- **【函数名称】 __onRegSuccess
- **【函数功能】 设备注册成功处理函数
- **【参数】 linkContent:注册段信息
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__onRegSuccess(const PduLinkContent& linkContent)
- {
- switch (linkContent.nFarType)
- {
- case PDU_DEV_TYPE_ACD:
- {
- // 保存设备信息
- m_DevAcd.DevId = linkContent.nLocalId;
- lstrcpy(m_DevAcd.szIpAddress, linkContent.szFarIp);
- m_DevAcd.Port = linkContent.nFarPort;
- m_IsAcdConnected = TRUE;
- // 通知线路类Acd连接成功
- CLineHolder::GetInstance().onAcdConnected();
- }
- break;
- case PDU_DEV_TYPE_IVR:
- {
- // 保存设备信息
- m_DevIvr.DevId = linkContent.nLocalId;
- lstrcpy(m_DevIvr.szIpAddress, linkContent.szFarIp);
- m_DevIvr.Port = linkContent.nFarPort;
- m_IsIvrConnected = TRUE;
- }
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 __onDisconnect
- **【函数功能】 设备连接断开处理函数
- **【参数】 linkContent:连接断开端信息
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__onDisconnect(const PduLinkContent& linkContent)
- {
- switch (linkContent.nFarType)
- {
- case PDU_DEV_TYPE_ACD:
- {
- if (m_DevAcd.DevId != linkContent.nLocalId) return;
- if (strcmp(m_DevAcd.szIpAddress, linkContent.szFarIp) != 0) return;
- if (m_DevAcd.Port != linkContent.nFarPort) return;
- memset(&m_DevAcd, 0, sizeof(m_DevAcd));
- m_DevAcd.DevId = -1;
- m_IsAcdConnected = FALSE;
- }
- break;
- case PDU_DEV_TYPE_IVR:
- {
- if (m_DevIvr.DevId != linkContent.nLocalId) return;
- if (strcmp(m_DevIvr.szIpAddress, linkContent.szFarIp) != 0) return;
- if (m_DevIvr.Port != linkContent.nFarPort) return;
- memset(&m_DevIvr, 0, sizeof(m_DevIvr));
- m_DevIvr.DevId = -1;
- // 通知IvrFlow IVR连接断开
- CIvrFlowHolder::GetInstance().onIvrDisconnect();
- m_IsIvrConnected = FALSE;
- }
- break;
- default:
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 OnLinkStateChanged
- **【函数功能】 连接状态信息变化
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetworkCti::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: // 连接已断开
- {
- Msg.Format(_T("{Net}: Far End[IP = %s, Port = %d], Hint = 网络连接已断开..."),
- linkContent.szFarIp,
- linkContent.nFarPort);
- Level = LOG_LEVEL_ERROR;
- // 通知IvrFlow IVR连接断开
- CIvrFlowHolder::GetInstance().onIvrDisconnect();
- m_IsIvrConnected = FALSE;
- m_IsAcdConnected = FALSE;
- }
- break;
- case PDU_LINK_STATE_REG_OK: // 注册成功
- {
- Msg.Format(_T("{Net}: Far End[Type = %d, ID = %d, IP = %s, Port = %d], Hint = 网络连接注册成功..."),
- 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, Level, "%s", Msg);
- }
- /*****************************************************************
- **【函数名称】 OnRecvCommand
- **【函数功能】 Pdu命令处理接口
- **【参数】 a_pPduEntity:消息实体
- **【返回值】
- ****************************************************************/
- void CNetworkCti::OnRecvCommand(CPduEntity* a_pPduEntity)
- {
- ASSERT(a_pPduEntity != NULL);
- if (a_pPduEntity->GetCmdType() != PDU_CMD_LISTEN) // 心跳命令不打印
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{CNetworkCti}:OnRecvCommand,CmdType=%d,LocalDevType[%d]"), a_pPduEntity->GetCmdType(), a_pPduEntity->GetLocalDevType());
- }
- switch (a_pPduEntity->GetCmdType())
- {
- case PDU_CMD_REG: // 注册命令
- __procRegMsg(*a_pPduEntity);
- break;
- case PDU_CMD_DEV_ONLINE_LIST: // 设备在线列表
- __procRegDevListMsg(*a_pPduEntity);
- break;
- case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令
- case PDU_CMD_CTI_IVR_TURNIVR: // 转IVR返回命令
- case PDU_CMD_IVR_HANGUP: // IVR通知CTI挂机
- case PDU_CMD_IVR_END: // IVR通知CTI流程结束
- case PDU_CMD_IVR_WANT_AGENT: // IVR通知CTI请求排队(包括ACD返回)
- case PDU_CMD_IVR_QUEUE_CONTINUE: // IVR通知CTI继续排队(包括ACD返回)
- case PDU_CMD_IVR_QUEUE_CANCEL: // IVR通知CTI取消排队
- case PDU_CMD_IVR_TURN_AGENT: // IVR通知CTI转坐席
- case PDU_CMD_IVR_PLAY_DTMF: // IVR通知CTI放音收按键
- case PDU_CMD_IVR_CALL_OUT: // IVR通知CTI自动呼叫某个号码
- case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
- case PDU_CMD_IVR_FAX: // IVR通知收发传真
- case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
- CIvrFlowHolder::GetInstance().onPduMessage(*a_pPduEntity);
- break;
- case PDU_CMD_LISTEN:
- return;
- case PDU_CMD_IVR_WAITER_COUNT: //2019 - 9 - 6 配合4.0acd返回排队人数
- {
- send2ACD(*a_pPduEntity); //发送至ACD
- int WaiterCount = a_pPduEntity->GetDataUInt(0);
- // m_WaiterCount.onWaiterCount(WaiterCount);
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{NetWorkCti}:收到排队数量%d", WaiterCount);
- }
- break;
- default:
- {
- __try {
- CTaskMgr::GetInstance().onPduMessage(*a_pPduEntity);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CNetworkCti}:OnRecvCommand,CTaskMgr异常,CmdType=%d,mdw5.1.19.1"), a_pPduEntity->GetCmdType());
- }
- break;
- }
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 init
- **【函数功能】 初始化
- **【参数】
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CNetworkCti::init()
- {
- // 初始化客户端设备信息
- memset(&m_DevAcd, 0, sizeof(m_DevAcd));
- memset(&m_DevIvr, 0, sizeof(m_DevIvr));
- m_DevAcd.DevId = -1;
- m_DevIvr.DevId = -1;
- auto pClient = CNetInterface::getNetInstance();
- pClient->setLinkStateChanged(std::bind(&CNetworkCti::OnLinkStateChanged, this, std::placeholders::_1));
- pClient->setRecvCommand(std::bind(&CNetworkCti::OnRecvCommand, this, std::placeholders::_1));
- //连接ws服务器端
- CString Ip = CConfig::GetInstance().wsIP();
- int Port = CConfig::GetInstance().wsPort();
- if(pClient->CreatePduClient(Ip, Port, PDU_DEV_TYPE_CTI, 1, true))
- {
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{Net}: 连接ws服务端成功,IP=%s,ListenPort = %d", Ip,Port);
- return TRUE;
- }
- else
- {
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "{Net}: 连接ws服务端失败,IP=%s,ListenPort = %d", Ip, Port);
- return FALSE;
- }
- return TRUE;
- }
- /*****************************************************************
- **【函数名称】 release
- **【函数功能】 释放资源
- **【参数】
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- void CNetworkCti::release(void)
- {
- CNetInterface::getNetInstance()->ClosePduClient(PDU_DEV_TYPE_CTI, 1);
- }
- /*****************************************************************
- **【函数名称】 send2ACD
- **【函数功能】 发送PDU到ACD
- **【参数】 a_PduEntity:待发送的PDU
- **【返回值】
- ****************************************************************/
- BOOL CNetworkCti::send2ACD(CPduEntity& a_PduEntity)
- {
- return CNetInterface::getNetInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_ACD, m_DevAcd.DevId);
- }
- /*****************************************************************
- **【函数名称】 send2IVR
- **【函数功能】 发送PDU到IVR
- **【参数】 a_PduEntity:待发送的PDU
- **【返回值】
- ****************************************************************/
- BOOL CNetworkCti::send2IVR(CPduEntity& a_PduEntity)
- {
- return CNetInterface::getNetInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_IVR, m_DevIvr.DevId);
- }
|