GrabBag/App/BeltTearing/BeltTearingServer/TearingTcpProtocol.h

218 lines
6.1 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 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
* @return 错误码0表示成功非0表示失败
*/
using SpeedCallback = std::function<int(int speed)>;
/**
* @brief 控制命令回调
* @param control true-启动false-停止
* @return 错误码0表示成功非0表示失败
*/
using ControlCallback = std::function<int(bool control)>;
/**
* @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<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);
/**
* @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<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; // 客户端超时时间(秒)
quint16 m_tcpPort; // TCP服务器端口
// 客户端数据缓冲区
QMap<QString, QByteArray> m_clientBuffers; // 客户端ID -> 数据缓冲区
QMap<QString, qint64> m_clientLastActive; // 客户端ID -> 最后活跃时间
// 回调函数
SpeedCallback m_speedCallback;
ControlCallback m_controlCallback;
};
#endif // TEARINGTCPPROTOCOL_H