209 lines
5.8 KiB
C
209 lines
5.8 KiB
C
|
|
#ifndef TEARINGTCPPROTOCOL_H
|
|||
|
|
#define TEARINGTCPPROTOCOL_H
|
|||
|
|
|
|||
|
|
#include <QObject>
|
|||
|
|
#include <QJsonObject>
|
|||
|
|
#include <QJsonDocument>
|
|||
|
|
#include <QByteArray>
|
|||
|
|
#include <QBuffer>
|
|||
|
|
#include <QImage>
|
|||
|
|
#include <QDateTime>
|
|||
|
|
#include <QTimer>
|
|||
|
|
#include <QMap>
|
|||
|
|
#include <functional>
|
|||
|
|
#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)
|
|||
|
|
*/
|
|||
|
|
using SpeedCallback = std::function<void(int speed)>;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 控制命令回调
|
|||
|
|
* @param control true-启动,false-停止
|
|||
|
|
*/
|
|||
|
|
using ControlCallback = std::function<void(bool control)>;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 撕裂TCP通信协议类
|
|||
|
|
* 实现皮带撕裂检测系统的TCP通信协议
|
|||
|
|
* 协议文档:撕裂TCP通信协议.md
|
|||
|
|
*/
|
|||
|
|
class TearingTcpProtocol : public QObject
|
|||
|
|
{
|
|||
|
|
Q_OBJECT
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
explicit TearingTcpProtocol(IYTCPServer* tcpServer, 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<SSG_beltTearingInfo>& 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);
|
|||
|
|
|
|||
|
|
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<QByteArray>& 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; // 客户端超时时间(秒)
|
|||
|
|
|
|||
|
|
// 客户端数据缓冲区
|
|||
|
|
QMap<QString, QByteArray> m_clientBuffers; // 客户端ID -> 数据缓冲区
|
|||
|
|
QMap<QString, qint64> m_clientLastActive; // 客户端ID -> 最后活跃时间
|
|||
|
|
|
|||
|
|
// 回调函数
|
|||
|
|
SpeedCallback m_speedCallback;
|
|||
|
|
ControlCallback m_controlCallback;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#endif // TEARINGTCPPROTOCOL_H
|