CWebsocketProc.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #include "CWebsocketProc.h"
  2. #include <QNetworkRequest>
  3. #include <QUrlQuery>
  4. #include <QCryptographicHash>
  5. #include "CCommonTools.h"
  6. #include "CAppInfo.h"
  7. #include "logproc.h"
  8. std::shared_ptr<CWebsocketProc> g_websocketPtr;
  9. CWebsocketProc::CWebsocketProc()
  10. {
  11. m_sToken = "";
  12. m_nTimeOutTimes = 0;
  13. m_nTimeOutLimit = 4;
  14. m_nTimeOutSecord = 10;
  15. m_bConnected = false;
  16. m_pWebsocket = new QWebSocket;
  17. m_isExitClosed = false;
  18. QSslConfiguration config = m_pWebsocket->sslConfiguration();
  19. config.setPeerVerifyMode(QSslSocket::VerifyNone);
  20. config.setProtocol(QSsl::TlsV1SslV3);
  21. m_pWebsocket->setSslConfiguration(config);
  22. m_pTime = new QTimer;
  23. connect(m_pTime, &QTimer::timeout, this, &CWebsocketProc::reconnect);
  24. connect(m_pWebsocket, &QWebSocket::disconnected, this, &CWebsocketProc::onDisconnected);
  25. bool ret = connect(m_pWebsocket, &QWebSocket::textMessageReceived, this, &CWebsocketProc::onTextReceived);
  26. ret = connect(m_pWebsocket, &QWebSocket::connected, this, &CWebsocketProc::onConnected);
  27. m_pHeartBeat = new QTimer;
  28. connect(m_pHeartBeat, SIGNAL(timeout()), this, SLOT(onHeartBreatTimeout()));
  29. m_pHeartBeat->setInterval(m_nTimeOutSecord*1000);
  30. m_pHeartBeat->start();
  31. }
  32. CWebsocketProc::~CWebsocketProc()
  33. {
  34. m_pWebsocket->errorString();
  35. m_pWebsocket->close();
  36. RELEASE_PTR(m_pWebsocket);
  37. m_pTime->stop();
  38. RELEASE_PTR(m_pTime);
  39. }
  40. void CWebsocketProc::setUrl(QString sUrl, QString sToken, QString sKey)
  41. {
  42. m_sUrl = sUrl;
  43. m_sToken = sToken;
  44. m_sKey = sKey;
  45. }
  46. void CWebsocketProc::open()
  47. {
  48. m_lastRecvTime = 0;
  49. m_isExitClosed = false;
  50. if(!m_sUrl.isEmpty())
  51. {
  52. QUrl url(m_sUrl);
  53. QUrlQuery urlQuery;
  54. urlQuery.addQueryItem("key", m_sKey);
  55. urlQuery.addQueryItem("token", m_sToken);
  56. url.setQuery(urlQuery);
  57. qDebug()<<url.url();
  58. m_pWebsocket->open(url);
  59. m_pTime->start(m_nTimeOutSecord*1000);
  60. myServerLog()<<url.url();
  61. }
  62. }
  63. void CWebsocketProc::open(QString sUrl, QString sToken, QString sKey)
  64. {
  65. m_sToken = sToken;
  66. m_sKey = sKey;
  67. m_sUrl = sUrl;
  68. open();
  69. }
  70. void CWebsocketProc::close()
  71. {
  72. m_isExitClosed = true;
  73. m_pTime->stop();
  74. m_bConnected = false;
  75. // m_pWebsocket->abort();
  76. m_pWebsocket->close();
  77. }
  78. bool CWebsocketProc::isConnected()
  79. {
  80. return m_bConnected;
  81. }
  82. void CWebsocketProc::onHeartBreatTimeout()
  83. {
  84. qDebug() << "onHeartBreatTimeout";
  85. int nCurTime = g_appInfoPtr->serverMTime();
  86. if(m_lastRecvTime != 0 && nCurTime - m_lastRecvTime > m_nTimeOutSecord*3*1000)
  87. {
  88. close();
  89. open();
  90. emit networkWeak();
  91. return;
  92. }
  93. if(m_bConnected)
  94. {
  95. qint64 len = sendText("{eventType: \"HEARTBEAT\"}");
  96. myDebug()<<len;
  97. }
  98. else
  99. {
  100. }
  101. }
  102. qint64 CWebsocketProc::sendText(QString sText)
  103. {
  104. if(m_bConnected)
  105. {
  106. // QByteArray data = sText.remove(QRegExp("\\s")).toLatin1();
  107. qDebug()<<sText;
  108. return m_pWebsocket->sendTextMessage(sText);
  109. }
  110. else
  111. {
  112. return 0;
  113. }
  114. }
  115. //断开连接会触发这个槽函数
  116. void CWebsocketProc::onDisconnected()
  117. {
  118. qDebug() << m_pWebsocket->errorString();
  119. m_bConnected = false;
  120. if(!m_isExitClosed)
  121. {
  122. m_pTime->start(m_nTimeOutSecord*1000);
  123. emit networkWeak();
  124. }
  125. qDebug()<<"Websocket Disconnected";
  126. myServerLog() <<"Websocket Disconnected";
  127. }
  128. //连接成功会触发这个槽函数
  129. void CWebsocketProc::onConnected()
  130. {
  131. m_bConnected = true;
  132. m_nTimeOutTimes = 0;
  133. m_pTime->stop();
  134. emit connected();
  135. qDebug()<<"Websocket Connected";
  136. myServerLog()<<"Websocket Connected";
  137. }
  138. //收到服务发来的消息会触发这个槽函数
  139. void CWebsocketProc::onTextReceived(QString msg)
  140. {
  141. try
  142. {
  143. qDebug()<<"recv:"<<msg;
  144. myServerLog()<<"recv:"<<msg;
  145. m_lastRecvTime = g_appInfoPtr->serverMTime();
  146. Json::Value jRececvMsg = Json::Value::null;
  147. Json::Reader reader;
  148. if(!reader.parse(msg.toStdString(), jRececvMsg))
  149. {
  150. myServerLog() << QString::fromLocal8Bit("解析后台数据出错:") << msg;
  151. emit websocketError("解析后台数据出错");
  152. return;
  153. }
  154. QString sCode = jRececvMsg["status"]["code"].asString().c_str();
  155. if (sCode != "200")
  156. {
  157. emit websocketError(jRececvMsg["status"]["desc"].asString().c_str());
  158. }
  159. else
  160. {
  161. QString sType = jRececvMsg["content"]["eventType"].asString().c_str();
  162. if (sType == "SCAN_QR_CODE")//移动端拍照/录音扫描完成
  163. {
  164. if (jRececvMsg["content"]["isSuccess"].asBool())
  165. {
  166. QString sScanStatus = jRececvMsg["content"]["data"]["scanStatus"].asString().c_str();
  167. __int64 nExamRecordDataId = jRececvMsg["content"]["data"]["examRecordDataId"].asInt64();
  168. int nOrder = jRececvMsg["content"]["data"]["order"].asInt();
  169. emit mobileStatus(nExamRecordDataId, nOrder, sScanStatus);
  170. }
  171. else
  172. {
  173. QString sErrorMsg = jRececvMsg["content"]["errorMessage"].asString().c_str();
  174. emit websocketError(sErrorMsg);
  175. }
  176. }
  177. else if (sType == "GET_FILE_ANSWER")//移动端拍照/录音上传成功
  178. {
  179. if (jRececvMsg["content"]["isSuccess"].asBool())
  180. {
  181. QString sFileType = jRececvMsg["content"]["data"]["transferFileType"].asString().c_str();
  182. QString sFileUrl = jRececvMsg["content"]["data"]["fileUrl"].asString().c_str();
  183. __int64 nExamRecordDataId = jRececvMsg["content"]["data"]["examRecordDataId"].asInt64();
  184. int nOrder = jRececvMsg["content"]["data"]["order"].asInt();
  185. emit fileAnswer(nExamRecordDataId, nOrder, sFileType, sFileUrl);
  186. }
  187. else
  188. {
  189. QString sErrorMsg = jRececvMsg["content"]["errorMessage"].asString().c_str();
  190. emit websocketError(sErrorMsg);
  191. }
  192. }
  193. }
  194. m_bConnected = true;
  195. m_nTimeOutTimes = 0;
  196. m_pTime->stop();
  197. }
  198. catch (std::exception &e)
  199. {
  200. emit websocketError(QString::fromLocal8Bit("接收数据出错:%1").arg(e.what()));
  201. }
  202. }
  203. //断开连接会启动定时器,触发这个槽函数重新连接
  204. void CWebsocketProc::reconnect()
  205. {
  206. m_nTimeOutTimes++;
  207. if(m_nTimeOutTimes > m_nTimeOutLimit)
  208. {
  209. emit clientOffLine();
  210. return;
  211. }
  212. else
  213. {
  214. emit networkWeak();
  215. }
  216. m_bConnected = false;
  217. m_pWebsocket->abort();
  218. open();
  219. }