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

88 lines
2.9 KiB
C
Raw Normal View History

2026-07-20 11:52:35 +08:00
#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