88 lines
2.9 KiB
C++
88 lines
2.9 KiB
C++
#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
|