#include "CWebsocketProc.h" #include #include #include #include "CCommonTools.h" #include "CAppInfo.h" #include "logproc.h" std::shared_ptr g_websocketPtr; CWebsocketProc::CWebsocketProc() { m_sToken = ""; m_nTimeOutTimes = 0; m_nTimeOutLimit = 4; m_nTimeOutSecord = 10; m_bConnected = false; m_pWebsocket = new QWebSocket; m_isExitClosed = false; QSslConfiguration config = m_pWebsocket->sslConfiguration(); config.setPeerVerifyMode(QSslSocket::VerifyNone); config.setProtocol(QSsl::TlsV1SslV3); m_pWebsocket->setSslConfiguration(config); m_pTime = new QTimer; connect(m_pTime, &QTimer::timeout, this, &CWebsocketProc::reconnect); connect(m_pWebsocket, &QWebSocket::disconnected, this, &CWebsocketProc::onDisconnected); bool ret = connect(m_pWebsocket, &QWebSocket::textMessageReceived, this, &CWebsocketProc::onTextReceived); ret = connect(m_pWebsocket, &QWebSocket::connected, this, &CWebsocketProc::onConnected); m_pHeartBeat = new QTimer; connect(m_pHeartBeat, SIGNAL(timeout()), this, SLOT(onHeartBreatTimeout())); m_pHeartBeat->setInterval(m_nTimeOutSecord*1000); m_pHeartBeat->start(); } CWebsocketProc::~CWebsocketProc() { m_pWebsocket->errorString(); m_pWebsocket->close(); RELEASE_PTR(m_pWebsocket); m_pTime->stop(); RELEASE_PTR(m_pTime); } void CWebsocketProc::setUrl(QString sUrl, QString sToken, QString sKey) { m_sUrl = sUrl; m_sToken = sToken; m_sKey = sKey; } void CWebsocketProc::open() { m_lastRecvTime = 0; m_isExitClosed = false; if(!m_sUrl.isEmpty()) { QUrl url(m_sUrl); QUrlQuery urlQuery; urlQuery.addQueryItem("key", m_sKey); urlQuery.addQueryItem("token", m_sToken); url.setQuery(urlQuery); qDebug()<open(url); m_pTime->start(m_nTimeOutSecord*1000); myServerLog()<stop(); m_bConnected = false; // m_pWebsocket->abort(); m_pWebsocket->close(); } bool CWebsocketProc::isConnected() { return m_bConnected; } void CWebsocketProc::onHeartBreatTimeout() { qDebug() << "onHeartBreatTimeout"; int nCurTime = g_appInfoPtr->serverMTime(); if(m_lastRecvTime != 0 && nCurTime - m_lastRecvTime > m_nTimeOutSecord*3*1000) { close(); open(); emit networkWeak(); return; } if(m_bConnected) { qint64 len = sendText("{eventType: \"HEARTBEAT\"}"); myDebug()<sendTextMessage(sText); } else { return 0; } } //断开连接会触发这个槽函数 void CWebsocketProc::onDisconnected() { qDebug() << m_pWebsocket->errorString(); m_bConnected = false; if(!m_isExitClosed) { m_pTime->start(m_nTimeOutSecord*1000); emit networkWeak(); } qDebug()<<"Websocket Disconnected"; myServerLog() <<"Websocket Disconnected"; } //连接成功会触发这个槽函数 void CWebsocketProc::onConnected() { m_bConnected = true; m_nTimeOutTimes = 0; m_pTime->stop(); emit connected(); qDebug()<<"Websocket Connected"; myServerLog()<<"Websocket Connected"; } //收到服务发来的消息会触发这个槽函数 void CWebsocketProc::onTextReceived(QString msg) { try { qDebug()<<"recv:"<serverMTime(); Json::Value jRececvMsg = Json::Value::null; Json::Reader reader; if(!reader.parse(msg.toStdString(), jRececvMsg)) { myServerLog() << QString::fromLocal8Bit("解析后台数据出错:") << msg; emit websocketError("解析后台数据出错"); return; } QString sCode = jRececvMsg["status"]["code"].asString().c_str(); if (sCode != "200") { emit websocketError(jRececvMsg["status"]["desc"].asString().c_str()); } else { QString sType = jRececvMsg["content"]["eventType"].asString().c_str(); if (sType == "SCAN_QR_CODE")//移动端拍照/录音扫描完成 { if (jRececvMsg["content"]["isSuccess"].asBool()) { QString sScanStatus = jRececvMsg["content"]["data"]["scanStatus"].asString().c_str(); __int64 nExamRecordDataId = jRececvMsg["content"]["data"]["examRecordDataId"].asInt64(); int nOrder = jRececvMsg["content"]["data"]["order"].asInt(); emit mobileStatus(nExamRecordDataId, nOrder, sScanStatus); } else { QString sErrorMsg = jRececvMsg["content"]["errorMessage"].asString().c_str(); emit websocketError(sErrorMsg); } } else if (sType == "GET_FILE_ANSWER")//移动端拍照/录音上传成功 { if (jRececvMsg["content"]["isSuccess"].asBool()) { QString sFileType = jRececvMsg["content"]["data"]["transferFileType"].asString().c_str(); QString sFileUrl = jRececvMsg["content"]["data"]["fileUrl"].asString().c_str(); __int64 nExamRecordDataId = jRececvMsg["content"]["data"]["examRecordDataId"].asInt64(); int nOrder = jRececvMsg["content"]["data"]["order"].asInt(); emit fileAnswer(nExamRecordDataId, nOrder, sFileType, sFileUrl); } else { QString sErrorMsg = jRececvMsg["content"]["errorMessage"].asString().c_str(); emit websocketError(sErrorMsg); } } } m_bConnected = true; m_nTimeOutTimes = 0; m_pTime->stop(); } catch (std::exception &e) { emit websocketError(QString::fromLocal8Bit("接收数据出错:%1").arg(e.what())); } } //断开连接会启动定时器,触发这个槽函数重新连接 void CWebsocketProc::reconnect() { m_nTimeOutTimes++; if(m_nTimeOutTimes > m_nTimeOutLimit) { emit clientOffLine(); return; } else { emit networkWeak(); } m_bConnected = false; m_pWebsocket->abort(); open(); }