GrabBag/App/RodWeldSeam/RodWeldSeamApp/Presenter/Inc/RodWeldSeamTCPProtocol.h

88 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef RODWELDSEAMTCPPROTOCOL_H
#define RODWELDSEAMTCPPROTOCOL_H
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <mutex>
#include <set>
#include <string>
#include <QByteArray>
#include "IYTCPServer.h"
#include "RobotPose6D.h"
/**
* @brief 钢筋焊缝定位文本 TCP 协议服务端。
*
* 请求格式W{camera}_X_Y_Z_A_B_C\r\n
*
* 协议层只负责报文收发和解析,不依赖 Presenter 或检测结果类型。检测完成后,
* 上层通过 SendTextResult() 传入不含行结束符的结果正文,协议层追加 CRLF 并
* 广播给当前所有客户端。
*/
class RodWeldSeamTCPProtocol
{
public:
using ConnectionCallback = std::function<void(bool connected)>;
using DetectionTriggerCallback = std::function<bool(int cameraIndex,
const RobotPose6D& robotPose)>;
RodWeldSeamTCPProtocol();
~RodWeldSeamTCPProtocol();
RodWeldSeamTCPProtocol(const RodWeldSeamTCPProtocol&) = delete;
RodWeldSeamTCPProtocol& operator=(const RodWeldSeamTCPProtocol&) = delete;
int Initialize(uint16_t port = 7800);
void Deinitialize();
bool IsRunning() const;
std::size_t ClientCount() const;
void SetConnectionCallback(const ConnectionCallback& callback);
void SetDetectionTriggerCallback(const DetectionTriggerCallback& callback);
/**
* @brief 广播已格式化的结果正文。
* @param text 不含 CR/LF 行结束符的结果正文。
* @return 0=成功,-1=服务未运行,-2=发送失败。
*/
int SendTextResult(const std::string& text);
private:
static constexpr std::size_t kMaxClientBufferBytes = 64U * 1024U;
void OnTCPEvent(const TCPClient* client, TCPServerEventType eventType);
void OnTCPDataReceived(const TCPClient* client, const char* data, unsigned int length);
void ParseTextCommand(const TCPClient* client, const QByteArray& line);
int SendTextToClient(const TCPClient* client, const std::string& text);
void NotifyConnectionChanged(bool connected);
private:
// Initialize/Deinitialize 可能由配置更新和析构路径分别调用,需串行化生命周期。
mutable std::mutex m_lifecycleMutex;
// 保护服务指针以及发送操作;停止服务前先把 running 置为 false避免发送/释放竞争。
mutable std::mutex m_sendMutex;
// TCP 底层可能从多个工作线程回调,不同客户端的缓存和集合共用此锁。
mutable std::mutex m_clientMutex;
mutable std::mutex m_callbackMutex;
IYTCPServer* m_tcpServer = nullptr;
std::atomic<bool> m_serverRunning{false};
std::atomic<std::size_t> m_clientCount{0};
uint16_t m_port = 7800;
std::map<const TCPClient*, QByteArray> m_clientBuffers;
std::set<const TCPClient*> m_clients;
ConnectionCallback m_connectionCallback;
DetectionTriggerCallback m_detectionTriggerCallback;
};
#endif // RODWELDSEAMTCPPROTOCOL_H