#ifndef TEARINGTCPPROTOCOL_H #define TEARINGTCPPROTOCOL_H #include #include #include #include #include #include #include #include #include #include #include "IYTCPServer.h" #include "beltTearingDetection_Export.h" // 帧格式定义 #define FRAME_HEADER "##START#" // 8字节帧头 #define FRAME_TAIL "#END" // 4字节帧尾 #define FRAME_HEADER_SIZE 8 #define FRAME_TAIL_SIZE 4 #define FRAME_LENGTH_SIZE 8 /** * @brief 消息类型枚举 */ enum class TcpMessageType { DETECT_RESULT, // 撕裂检测结果上报 SET_SPEED, // 设置速度命令 SET_CONTROL, // 启停控制命令 CMD_RESPONSE, // 命令应答 HEARTBEAT, // 心跳消息 HEARTBEAT_ACK, // 心跳应答 UNKNOWN // 未知消息类型 }; /** * @brief 速度设置回调 * @param speed 速度值(mm/s) * @return 错误码,0表示成功,非0表示失败 */ using SpeedCallback = std::function; /** * @brief 控制命令回调 * @param control true-启动,false-停止 * @return 错误码,0表示成功,非0表示失败 */ using ControlCallback = std::function; /** * @brief 撕裂TCP通信协议类 * 实现皮带撕裂检测系统的TCP通信协议 * 协议文档:撕裂TCP通信协议.md */ class TearingTcpProtocol : public QObject { Q_OBJECT public: explicit TearingTcpProtocol(QObject *parent = nullptr); ~TearingTcpProtocol(); /** * @brief 启动协议处理 * @param heartbeatInterval 心跳间隔(秒),默认30秒 */ void start(int heartbeatInterval = 30); /** * @brief 停止协议处理 */ void stop(); /** * @brief 发送撕裂检测结果 * @param results 检测结果数组 * @param visImage 可视化图像 */ void sendDetectResult(const std::vector& results, const QImage& visImage); /** * @brief 处理接收到的数据 * @param pClient 客户端指针 * @param pData 数据指针 * @param nLen 数据长度 */ void handleReceivedData(const TCPClient* pClient, const char* pData, unsigned int nLen); /** * @brief 设置速度设置回调 */ void setSpeedCallback(const SpeedCallback& callback); /** * @brief 设置控制命令回调 */ void setControlCallback(const ControlCallback& callback); /** * @brief 设置TCP端口 * @param port TCP端口 */ void setTcpPort(quint16 port); private slots: /** * @brief 心跳定时器超时处理 */ void onHeartbeatTimeout(); /** * @brief 客户端超时检查 */ void onClientTimeoutCheck(); private: /** * @brief 构造数据帧 * @param jsonData JSON数据 * @return 完整的数据帧 */ QByteArray buildFrame(const QByteArray& jsonData); /** * @brief 解析数据帧 * @param data 接收到的数据 * @param outJsonData 输出的JSON数据数组 * @return 成功解析的帧数量 */ int parseFrames(const QByteArray& data, QList& outJsonData); /** * @brief 解析消息类型 * @param msgTypeStr 消息类型字符串 * @return 消息类型枚举 */ TcpMessageType parseMessageType(const QString& msgTypeStr); /** * @brief 处理JSON消息 * @param pClient 客户端指针 * @param jsonData JSON数据 */ void handleJsonMessage(const TCPClient* pClient, const QByteArray& jsonData); /** * @brief 处理速度设置命令 * @param pClient 客户端指针 * @param jsonObj JSON对象 */ void handleSetSpeed(const TCPClient* pClient, const QJsonObject& jsonObj); /** * @brief 处理控制命令 * @param pClient 客户端指针 * @param jsonObj JSON对象 */ void handleSetControl(const TCPClient* pClient, const QJsonObject& jsonObj); /** * @brief 处理心跳消息 * @param pClient 客户端指针 * @param jsonObj JSON对象 */ void handleHeartbeat(const TCPClient* pClient, const QJsonObject& jsonObj); /** * @brief 发送命令应答 * @param pClient 客户端指针 * @param cmdType 命令类型 * @param result 执行结果 * @param errorCode 错误码 * @param errorMsg 错误消息 */ void sendCommandResponse(const TCPClient* pClient, const QString& cmdType, bool result, int errorCode, const QString& errorMsg); /** * @brief 发送心跳应答 * @param pClient 客户端指针 */ void sendHeartbeatAck(const TCPClient* pClient); /** * @brief 图像转Base64 * @param image 图像 * @return Base64字符串 */ QString imageToBase64(const QImage& image); /** * @brief 生成客户端ID * @param pClient 客户端指针 * @return 客户端ID */ QString generateClientId(const TCPClient* pClient); private: IYTCPServer* m_tcpServer; // TCP服务器 QTimer* m_heartbeatTimer; // 心跳定时器 QTimer* m_clientCheckTimer; // 客户端超时检查定时器 int m_heartbeatInterval; // 心跳间隔(秒) int m_clientTimeout; // 客户端超时时间(秒) quint16 m_tcpPort; // TCP服务器端口 // 客户端数据缓冲区 QMap m_clientBuffers; // 客户端ID -> 数据缓冲区 QMap m_clientLastActive; // 客户端ID -> 最后活跃时间 // 回调函数 SpeedCallback m_speedCallback; ControlCallback m_controlCallback; }; #endif // TEARINGTCPPROTOCOL_H