中间件底层,websocket

DingDing.cpp 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "pch.h"
  2. #include <mutex>
  3. #include <memory>
  4. #include <list>
  5. #include "DingDing.h"
  6. #include "HttpClient.h"
  7. #include "ConfigFile.h"
  8. typedef struct PushRecord {
  9. std::string strType; // 类型,消息内容也可以
  10. std::int64_t nFirstTime; // 最近一次消息时间戳,秒
  11. std::int32_t nTimeOut; // 超时时间,单位秒
  12. std::int16_t nTotalCount; // 总需累积次数
  13. std::int16_t nCurCount; // 当前累积次数
  14. PushRecord(const std::string& strType, const std::int32_t& nTimeOut, const std::int16_t& nTotalCount) {
  15. this->strType = strType;
  16. this->nFirstTime = time(NULL);
  17. this->nTimeOut = nTimeOut;
  18. this->nTotalCount = nTotalCount;
  19. this->nCurCount = 0;
  20. }
  21. bool IsPush() {
  22. this->nCurCount++;
  23. if ((time(NULL) - this->nFirstTime) < nTimeOut && this->nCurCount >= this->nTotalCount) { // 该条件满足, 重置计数,便于下次计算
  24. this->nFirstTime = time(NULL);
  25. this->nCurCount = 0;
  26. return true;
  27. }
  28. return false;
  29. }
  30. }CPushRecord;
  31. bool CDingDing::Push(const std::string & strInfo)
  32. {
  33. auto cfig = CConfigFile::getInstance();
  34. if (!cfig->isPush()) return false;
  35. std::string content = cfig->projectName() + "\n[" + strInfo + "]";
  36. Json::Value root;
  37. Json::Value child;
  38. Json::Value third;
  39. Json::StreamWriterBuilder builder;
  40. const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
  41. third["isAtAll"] = true;
  42. child["at"] = third;
  43. third.clear();
  44. child["msgtype"] = "text";
  45. third["content"] = ansi_to_utf8(content);
  46. child["text"] = third;
  47. root = child;
  48. content = Json::writeString(builder, root);
  49. std::string resp;
  50. auto eCode = CHttpClient::GetInStance()->curl_post_req(cfig->pushUrl().c_str(), content.c_str(), resp);
  51. return CURLE_OK == eCode ? true : false;
  52. }
  53. bool CDingDing::PushHeart(const std::string & strDev)
  54. {
  55. std::string strPushInfo = "";
  56. strPushInfo = "[" + strDev + "] 心跳超时,请尽快检测程序是否运行正常";
  57. return Push(strPushInfo);
  58. }
  59. bool CDingDing::PushHeart(const std::string & strDev, const bool & bIsPush, const bool& bIsRm)
  60. {
  61. auto cfig = CConfigFile::getInstance();
  62. if (!cfig->isPush()) return false;
  63. static std::map<std::string, std::int64_t> mapDev;
  64. static std::mutex mut;
  65. std::stringstream ssPushInfo;
  66. std::unique_lock<std::mutex>lock(mut);
  67. if (bIsRm) { // 是否移除监听
  68. mapDev.erase(strDev);
  69. }
  70. else {
  71. if (bIsPush) { // 更新时间戳
  72. mapDev[strDev] = time(NULL);
  73. }
  74. else { // 不移除,不更新,说明在需要遍历是否心跳超时
  75. // 遍历当前设备列表每个设备最近的消息时间
  76. std::list<std::string> ltPushInfo; // 待推送消息
  77. std::int64_t lTimeStamp = 0;
  78. std::int64_t lCurTime = time(NULL);
  79. auto it = mapDev.begin();
  80. while (it != mapDev.end()) {
  81. ssPushInfo.str("");
  82. ssPushInfo.clear();
  83. lTimeStamp = lCurTime - it->second;
  84. if (lTimeStamp > cfig->heartTimeOut()) {
  85. ssPushInfo << "[" << it->first << "] 心跳超时,请尽快检测程序是否运行正常;\n";
  86. ssPushInfo << "当前配置超时时间为:" << cfig->heartTimeOut() << "秒;\n";
  87. ssPushInfo << "实际超时时间为:" << lTimeStamp << "秒;\n";
  88. ltPushInfo.emplace_back(ssPushInfo.str());
  89. it = mapDev.erase(it);
  90. }
  91. else {
  92. ++it;
  93. }
  94. }
  95. lock.unlock();
  96. // 推送到钉钉
  97. for (auto pushInfo : ltPushInfo) {
  98. Push(pushInfo);
  99. }
  100. }
  101. }
  102. return true;
  103. }
  104. bool CDingDing::PushDisConn(const std::string & strDev)
  105. {
  106. std::string strPushInfo = "";
  107. strPushInfo = "[" + strDev + "] 网络连接断开,请尽快检测程序是否运行正常";
  108. return Push(strPushInfo);
  109. }
  110. bool CDingDing::PushIVRCellTimeOut()
  111. {
  112. // 60秒内触发5次就提醒
  113. static CPushRecord pushRecord("IVR-流程超时提醒", 60, 5);
  114. if (pushRecord.IsPush()) {
  115. return Push(pushRecord.strType);
  116. }
  117. return true;
  118. }
  119. bool CDingDing::PushFailSQL(const std::string & strSql, const std::string& strErrInfo)
  120. {
  121. std::string strPushInfo = "";
  122. strPushInfo = "SQL执行失败,错误信息:[" + strErrInfo + "];SQL=[" + strSql + "]";
  123. return Push(strPushInfo);
  124. }
  125. bool CDingDing::PushFindFailChan()
  126. {
  127. // 60秒内触发5次就提醒
  128. static CPushRecord pushRecord("处理通道事件时查找对应通道失败", 60, 5);
  129. if (pushRecord.IsPush()) {
  130. return Push(pushRecord.strType);
  131. }
  132. return true;
  133. }
  134. CDingDing CDingDing::instance;
  135. extern "C" DINGDING_API IDingDing* GetDingDing() {
  136. return CDingDing::GetInstance();
  137. }
  138. //extern "C" DINGDING_API IDingDing* GetInstance() {
  139. // return CDingDing::GetInstance();
  140. //};