WebSocketHandler.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. #include "WebSocketHandler.h"
  2. #include "WebSocketSession.h"
  3. #include "rapidjson/document.h"
  4. #include "rapidjson/writer.h"
  5. #include "rapidjson/stringbuffer.h"
  6. #include "Logger.h"
  7. #include <algorithm>
  8. #include <chrono>
  9. WebSocketHandler::WebSocketHandler(bool use_dll) : use_dll_(use_dll), timeout_thread_running_(false)
  10. {
  11. if (use_dll_)
  12. {
  13. comm_wrapper_ = std::make_shared<DllWrapper>();
  14. }
  15. else
  16. {
  17. comm_wrapper_ = std::make_shared<ActiveXWrapper>();
  18. }
  19. }
  20. WebSocketHandler::~WebSocketHandler()
  21. {
  22. Cleanup();
  23. }
  24. bool WebSocketHandler::Initialize()
  25. {
  26. if (!comm_wrapper_->Initialize())
  27. {
  28. LOG_ERROR("Failed to initialize communication wrapper");
  29. return false;
  30. }
  31. // 设置事件回调
  32. comm_wrapper_->SetEventCallback([this](const CommEventData &event_data)
  33. { OnCommEvent(event_data); });
  34. // 初始化监控
  35. if (!comm_wrapper_->InitMonitor())
  36. {
  37. LOG_ERROR("Failed to initialize communication monitor");
  38. return false;
  39. }
  40. // 启动超时检测线程
  41. //timeout_thread_running_ = true;
  42. //timeout_check_thread_ = std::thread(&WebSocketHandler::TimeoutCheckThread, this);
  43. LOG_INFO("WebSocketHandler initialized successfully");
  44. return true;
  45. }
  46. void WebSocketHandler::AddClient(std::shared_ptr<WebSocketSession> session)
  47. {
  48. std::lock_guard<std::mutex> lock(clients_mutex_);
  49. connected_clients_.insert(session);
  50. LOG_INFO("Client connected, total clients: " + std::to_string(connected_clients_.size()));
  51. }
  52. void WebSocketHandler::RemoveClient(std::shared_ptr<WebSocketSession> session)
  53. {
  54. std::lock_guard<std::mutex> lock(clients_mutex_);
  55. // 从连接客户端集合中移除
  56. connected_clients_.erase(session);
  57. // 关闭WebSocket连接
  58. session->close();
  59. LOG_INFO("Client disconnected, total clients: " + std::to_string(connected_clients_.size()));
  60. }
  61. void WebSocketHandler::HandleMessage(std::shared_ptr<WebSocketSession> session, const std::string &message)
  62. {
  63. rapidjson::Document doc;
  64. if (doc.Parse(message.c_str()).HasParseError())
  65. {
  66. LOG_ERROR("Failed to parse JSON message: " + message);
  67. return;
  68. }
  69. if (!doc.HasMember("cmd") || !doc["cmd"].IsString())
  70. {
  71. LOG_ERROR("Invalid message format: missing 'cmd' field");
  72. return;
  73. }
  74. std::string cmd = doc["cmd"].GetString();
  75. if (cmd == "InitMonitor")
  76. {
  77. if (!doc.HasMember("port") || !doc["port"].IsInt())
  78. {
  79. LOG_ERROR("Invalid InitMonitor message: missing 'port' field");
  80. return;
  81. }
  82. int port = doc["port"].GetInt();
  83. HandleInitMonitor(session, port);
  84. }
  85. else if (cmd == "StopPort")
  86. {
  87. if (!doc.HasMember("port") || !doc["port"].IsInt())
  88. {
  89. LOG_ERROR("Invalid StopPort message: missing 'port' field");
  90. return;
  91. }
  92. int port = doc["port"].GetInt();
  93. HandleStopPort(session, port);
  94. }
  95. else if (cmd == "ReadData")
  96. {
  97. if (!doc.HasMember("port") || !doc["port"].IsInt() ||
  98. !doc.HasMember("data") || !doc["data"].IsString())
  99. {
  100. LOG_ERROR("Invalid ReadData message: missing required fields");
  101. return;
  102. }
  103. int port = doc["port"].GetInt();
  104. std::string data = doc["data"].GetString();
  105. HandleReadData(session, port, data);
  106. }
  107. else if (cmd == "WriteData")
  108. {
  109. if (!doc.HasMember("port") || !doc["port"].IsInt() ||
  110. !doc.HasMember("data") || !doc["data"].IsString())
  111. {
  112. LOG_ERROR("Invalid WriteData message: missing required fields");
  113. return;
  114. }
  115. int port = doc["port"].GetInt();
  116. std::string data = doc["data"].GetString();
  117. HandleWriteData(session, port, data);
  118. }
  119. else
  120. {
  121. LOG_ERROR("Unknown command: " + cmd);
  122. }
  123. }
  124. void WebSocketHandler::HandleInitMonitor(std::shared_ptr<WebSocketSession> session, int port)
  125. {
  126. bool result = comm_wrapper_->MonitorPort(port);
  127. SendResponse(session, "InitMonitor", result, port);
  128. if (!result)
  129. {
  130. int error_code = comm_wrapper_->GetLastError();
  131. std::string error_msg = comm_wrapper_->GetErrorMessage(error_code);
  132. LOG_ERROR("InitMonitor failed for port " + std::to_string(port) + ": " + error_msg);
  133. }
  134. }
  135. void WebSocketHandler::HandleStopPort(std::shared_ptr<WebSocketSession> session, int port)
  136. {
  137. bool result = comm_wrapper_->StopPort(port);
  138. SendResponse(session, "StopPort", result, port);
  139. }
  140. void WebSocketHandler::HandleReadData(std::shared_ptr<WebSocketSession> session, int port, const std::string &data)
  141. {
  142. // 移除端口活动时间
  143. RemovePortActivity(port);
  144. bool result = comm_wrapper_->ReadData(port, data);
  145. SendResponse(session, "ReadData", result, port);
  146. }
  147. void WebSocketHandler::HandleWriteData(std::shared_ptr<WebSocketSession> session, int port, const std::string &data)
  148. {
  149. // 移除端口活动时间
  150. RemovePortActivity(port);
  151. bool result = comm_wrapper_->WriteData(port, data);
  152. SendResponse(session, "WriteData", result, port);
  153. }
  154. void WebSocketHandler::SendResponse(std::shared_ptr<WebSocketSession> session, const std::string &cmd, bool result, int port)
  155. {
  156. rapidjson::StringBuffer buffer;
  157. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  158. writer.StartObject();
  159. writer.Key("cmd");
  160. writer.String(cmd.c_str());
  161. writer.Key("result");
  162. writer.Bool(result);
  163. if (port > 0)
  164. {
  165. writer.Key("port");
  166. writer.Int(port);
  167. }
  168. writer.EndObject();
  169. std::string response = buffer.GetString();
  170. auto message = std::make_shared<std::string>(response);
  171. session->safe_send(message);
  172. LOG_DEBUG("Sent response: " + response);
  173. }
  174. void WebSocketHandler::BroadcastEvent(const std::string &cmd, int port, const std::string &data)
  175. {
  176. rapidjson::StringBuffer buffer;
  177. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  178. writer.StartObject();
  179. writer.Key("cmd");
  180. writer.String(cmd.c_str());
  181. writer.Key("port");
  182. writer.Int(port);
  183. if (!data.empty())
  184. {
  185. writer.Key("data");
  186. writer.String(data.c_str());
  187. }
  188. writer.EndObject();
  189. std::string event_message = buffer.GetString();
  190. auto message = std::make_shared<std::string>(event_message);
  191. std::lock_guard<std::mutex> lock(clients_mutex_);
  192. for (auto &client : connected_clients_)
  193. {
  194. client->safe_send(message);
  195. }
  196. LOG_DEBUG(std::to_string(connected_clients_.size()) + " Broadcasted event: " + event_message);
  197. }
  198. void WebSocketHandler::Cleanup()
  199. {
  200. // 停止超时检测线程
  201. if (timeout_thread_running_)
  202. {
  203. timeout_thread_running_ = false;
  204. if (timeout_check_thread_.joinable())
  205. {
  206. timeout_check_thread_.join();
  207. }
  208. }
  209. if (comm_wrapper_)
  210. {
  211. comm_wrapper_->Cleanup();
  212. }
  213. std::lock_guard<std::mutex> lock(clients_mutex_);
  214. connected_clients_.clear();
  215. LOG_INFO("WebSocketHandler cleaned up");
  216. }
  217. void WebSocketHandler::OnCommEvent(const CommEventData &event_data)
  218. {
  219. std::string cmd;
  220. std::string data_str;
  221. switch (event_data.event_type)
  222. {
  223. case CommEventType::OP_OPEN:
  224. cmd = "OP_OPEN";
  225. break;
  226. case CommEventType::OP_CLOSE:
  227. cmd = "OP_CLOSE";
  228. break;
  229. case CommEventType::OP_READ:
  230. cmd = "OP_READ";
  231. // 将字节数组转换为十六进制字符串
  232. for (size_t i = 0; i < event_data.data.size(); i++)
  233. {
  234. if (i > 0)
  235. data_str += " ";
  236. char hex[3];
  237. sprintf_s(hex, "%02X", event_data.data[i]);
  238. data_str += hex;
  239. }
  240. break;
  241. case CommEventType::OP_WRITE:
  242. cmd = "OP_WRITE";
  243. // 将字节数组转换为十六进制字符串
  244. for (size_t i = 0; i < event_data.data.size(); i++)
  245. {
  246. if (i > 0)
  247. data_str += " ";
  248. char hex[3];
  249. sprintf_s(hex, "%02X", event_data.data[i]);
  250. data_str += hex;
  251. }
  252. break;
  253. default:
  254. return; // 忽略未知事件
  255. }
  256. BroadcastEvent(cmd, event_data.port, data_str);
  257. switch (event_data.event_type)
  258. {
  259. case CommEventType::OP_READ:
  260. case CommEventType::OP_WRITE:
  261. // 更新端口活动时间
  262. UpdatePortActivity(event_data.port);
  263. break;
  264. default:
  265. break;
  266. }
  267. }
  268. void WebSocketHandler::UpdatePortActivity(int port)
  269. {
  270. std::lock_guard<std::mutex> lock(activity_mutex_);
  271. last_activity_time_[port] = std::chrono::steady_clock::now();
  272. }
  273. void WebSocketHandler::RemovePortActivity(int port)
  274. {
  275. std::lock_guard<std::mutex> lock(activity_mutex_);
  276. last_activity_time_.erase(port);
  277. }
  278. void WebSocketHandler::TimeoutCheckThread()
  279. {
  280. //while (timeout_thread_running_)
  281. //{
  282. // // 等待一段时间再检查
  283. // std::this_thread::sleep_for(std::chrono::seconds(5));
  284. // if (!timeout_thread_running_)
  285. // break;
  286. // // 获取当前时间
  287. // auto now = std::chrono::steady_clock::now();
  288. //
  289. // // 创建一个副本以避免在遍历时锁定
  290. // std::map<int, std::chrono::steady_clock::time_point> activity_copy;
  291. // {
  292. // std::lock_guard<std::mutex> lock(activity_mutex_);
  293. // activity_copy = last_activity_time_;
  294. // }
  295. // // 检查每个端口的活动时间
  296. // for (const auto &entry : activity_copy)
  297. // {
  298. // int port = entry.first;
  299. // auto last_activity = entry.second;
  300. //
  301. // // 计算自上次活动以来的时间
  302. // auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_activity).count();
  303. //
  304. // // 如果超过30秒没有活动,则停止监听该端口
  305. // if (duration >= TIMEOUT_SECONDS)
  306. // {
  307. // LOG_INFO("Port " + std::to_string(port) + " timeout, stopping monitoring");
  308. //
  309. // // 停止监听端口
  310. // if (comm_wrapper_)
  311. // {
  312. // comm_wrapper_->StopPort(port);
  313. // }
  314. //
  315. // // 从活动时间映射中移除该端口
  316. // {
  317. // std::lock_guard<std::mutex> lock(activity_mutex_);
  318. // last_activity_time_.erase(port);
  319. // }
  320. // }
  321. // }
  322. //}
  323. }