GrabBag/Module/BinocularMarkReceiver/_Inc/BinocularMarkReceiver.h
2025-12-10 00:01:32 +08:00

134 lines
4.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 BINOCULARMARKRECEIVER_H
#define BINOCULARMARKRECEIVER_H
#include "IBinocularMarkReceiver.h"
#include <QObject>
#include <QTcpSocket>
#include <QTimer>
#include <QByteArray>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <mutex>
/**
* @brief BinocularMarkReceiver实现类
* TCP客户端接收BinocularMarkApp发送的Mark检测结果
*/
class BinocularMarkReceiver : public QObject, public IBinocularMarkReceiver
{
Q_OBJECT
public:
explicit BinocularMarkReceiver(QObject *parent = nullptr);
~BinocularMarkReceiver() override;
// 实现IBinocularMarkReceiver接口
int Connect(const std::string& serverIp, quint16 serverPort) override;
int Disconnect() override;
bool IsConnected() const override;
int SendHeartbeat() override;
int TriggerDetection() override;
void SetMarkResultCallback(MarkResultCallback callback) override;
void SetConnectionStatusCallback(ConnectionStatusCallback callback) override;
void StartHeartbeat(int intervalSeconds = 30) override;
void StopHeartbeat() override;
private slots:
/**
* @brief 套接字连接成功槽函数
*/
void onConnected();
/**
* @brief 套接字断开连接槽函数
*/
void onDisconnected();
/**
* @brief 套接字错误槽函数
*/
void onError(QAbstractSocket::SocketError socketError);
/**
* @brief 套接字可读槽函数
*/
void onReadyRead();
/**
* @brief 心跳定时器超时槽函数
*/
void onHeartbeatTimeout();
private:
/**
* @brief 解析数据帧(处理粘包)
* @param data 接收到的数据
*/
void parseFrames(const QByteArray& data);
/**
* @brief 处理单个JSON消息
* @param jsonData JSON数据
*/
void handleJsonMessage(const QByteArray& jsonData);
/**
* @brief 处理Mark结果消息
* @param jsonObj JSON对象
*/
void handleMarkResult(const QJsonObject& jsonObj);
/**
* @brief 处理心跳应答消息
* @param jsonObj JSON对象
*/
void handleHeartbeatAck(const QJsonObject& jsonObj);
/**
* @brief 处理命令应答消息
* @param jsonObj JSON对象
*/
void handleCommandResponse(const QJsonObject& jsonObj);
/**
* @brief 构造数据帧
* @param jsonData JSON数据
* @return 完整的数据帧(帧头+长度+数据+帧尾)
*/
QByteArray buildFrame(const QByteArray& jsonData);
/**
* @brief 发送JSON消息
* @param messageType 消息类型
* @param jsonObj JSON对象
* @return 0-成功,其他-失败
*/
int sendJsonMessage(const QString& messageType, const QJsonObject& jsonObj);
private:
QTcpSocket* m_pTcpSocket; // TCP套接字
QTimer* m_pHeartbeatTimer; // 心跳定时器
int m_nHeartbeatInterval; // 心跳间隔(秒)
std::string m_serverIp; // 服务器IP
quint16 m_serverPort; // 服务器端口
bool m_bConnected; // 连接状态
QByteArray m_dataBuffer; // 数据缓冲区(处理粘包)
MarkResultCallback m_markResultCallback; // Mark结果回调
ConnectionStatusCallback m_connectionCallback; // 连接状态回调
mutable std::mutex m_mutex; // 线程安全锁
// 帧格式常量
static constexpr const char* FRAME_HEADER = "##START#"; // 8字节帧头
static constexpr const char* FRAME_TAIL = "#END"; // 4字节帧尾
static constexpr int FRAME_HEADER_SIZE = 8;
static constexpr int FRAME_TAIL_SIZE = 4;
static constexpr int FRAME_LENGTH_SIZE = 8; // 数据长度字段8字节ASCII字符串
};
#endif // BINOCULARMARKRECEIVER_H