GrabBag/App/WheelMeasure/WheelMeasureApp/Presenter/Src/WheelMeasureTCPProtocol.cpp

247 lines
6.6 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.

#include "WheelMeasureTCPProtocol.h"
#include "VrLog.h"
#include <QStringList>
WheelMeasureTCPProtocol::WheelMeasureTCPProtocol()
: m_pTCPServer(nullptr)
, m_bServerRunning(false)
, m_nPort(6800)
, m_pCurrentClient(nullptr)
{
}
WheelMeasureTCPProtocol::~WheelMeasureTCPProtocol()
{
Deinitialize();
}
int WheelMeasureTCPProtocol::Initialize(uint16_t port)
{
LOG_INFO("初始化车轮测量TCP服务器端口: %d\n", port);
m_nPort = port;
// 创建TCP服务器实例
if (!VrCreatYTCPServer(&m_pTCPServer)) {
LOG_ERROR("创建TCP服务器实例失败\n");
return -1;
}
// 初始化TCP服务器
if (!m_pTCPServer->Init(port)) {
LOG_ERROR("初始化TCP服务器失败端口: %d\n", port);
delete m_pTCPServer;
m_pTCPServer = nullptr;
return -2;
}
// 设置事件回调
m_pTCPServer->SetEventCallback([this](const TCPClient* pClient, TCPServerEventType eventType) {
this->OnTCPEvent(pClient, eventType);
});
// 启动TCP服务器
if (!m_pTCPServer->Start([this](const TCPClient* pClient, const char* pData, const unsigned int nLen) {
this->OnTCPDataReceived(pClient, pData, nLen);
})) {
LOG_ERROR("启动TCP服务器失败\n");
m_pTCPServer->Close();
delete m_pTCPServer;
m_pTCPServer = nullptr;
return -3;
}
m_bServerRunning = true;
LOG_INFO("车轮测量TCP服务器启动成功端口: %d\n", port);
return 0;
}
void WheelMeasureTCPProtocol::Deinitialize()
{
if (m_pTCPServer) {
LOG_INFO("停止车轮测量TCP服务器\n");
m_bServerRunning = false;
m_pCurrentClient = nullptr;
m_pTCPServer->Stop();
m_pTCPServer->Close();
delete m_pTCPServer;
m_pTCPServer = nullptr;
LOG_INFO("车轮测量TCP服务器已停止\n");
}
}
int WheelMeasureTCPProtocol::SendMeasureResults(const std::vector<CameraMeasureResult>& results)
{
if (!m_pTCPServer || !m_bServerRunning) {
LOG_ERROR("TCP服务器未运行\n");
return -1;
}
if (results.empty()) {
LOG_ERROR("测量结果为空\n");
return -2;
}
// 构建结果字符串1,100,200;2,100,200;3,100,200;4,100,200
// 或失败情况1,400;2,100,200;3,100,200;4,100,200
QString resultStr;
for (size_t i = 0; i < results.size(); ++i) {
const auto& result = results[i];
if (i > 0) {
resultStr += ";";
}
resultStr += QString::number(result.cameraId);
if (result.errorCode != 0) {
// 失败情况只发送相机ID和错误码
resultStr += "," + QString::number(result.errorCode);
} else {
// 成功情况发送相机ID、中心距离、轮眉距离
resultStr += "," + QString::number(static_cast<int>(result.centerDistance));
resultStr += "," + QString::number(static_cast<int>(result.archDistance));
}
}
LOG_INFO("发送测量结果: %s\n", resultStr.toStdString().c_str());
// 发送给当前请求的客户端
QMutexLocker locker(&m_mutex);
bool success = SendData(m_pCurrentClient, resultStr);
if (!success) {
LOG_ERROR("发送测量结果失败\n");
return -3;
}
return 0;
}
void WheelMeasureTCPProtocol::SetDetectionTriggerCallback(const DetectionTriggerCallback& callback)
{
m_detectionCallback = callback;
}
int WheelMeasureTCPProtocol::GetClientCount() const
{
// IYTCPServer 没有提供 GetClientCount 方法
// 返回服务器是否运行的状态
return m_bServerRunning ? 1 : 0;
}
void WheelMeasureTCPProtocol::OnTCPEvent(const TCPClient* pClient, TCPServerEventType eventType)
{
switch (eventType) {
case TCP_EVENT_CLIENT_CONNECTED:
{
LOG_INFO("客户端已连接: %s\n", pClient->m_szClientIP);
break;
}
case TCP_EVENT_CLIENT_DISCONNECTED:
{
LOG_INFO("客户端已断开: %s\n", pClient->m_szClientIP);
// 如果是当前请求的客户端断开,清除引用
QMutexLocker locker(&m_mutex);
if (m_pCurrentClient == pClient) {
m_pCurrentClient = nullptr;
}
break;
}
case TCP_EVENT_CLIENT_EXCEPTION:
{
LOG_WARNING("客户端异常: %s\n", pClient->m_szClientIP);
break;
}
default:
break;
}
}
void WheelMeasureTCPProtocol::OnTCPDataReceived(const TCPClient* pClient, const char* pData, unsigned int nLen)
{
if (!pData || nLen == 0) {
return;
}
// 转换为QString
QString command = QString::fromUtf8(pData, nLen).trimmed();
LOG_INFO("收到客户端命令: %s (来自 %s)\n",
command.toStdString().c_str(),
pClient->m_szClientIP);
// 解析命令
ParseCommand(pClient, command);
}
void WheelMeasureTCPProtocol::ParseCommand(const TCPClient* pClient, const QString& command)
{
// 命令格式start,100
QStringList parts = command.split(',');
if (parts.isEmpty()) {
LOG_WARNING("收到空命令\n");
return;
}
QString cmd = parts[0].trimmed().toLower();
if (cmd == "start") {
// 解析参数
int param = 100; // 默认值
if (parts.size() > 1) {
bool ok = false;
int parsedParam = parts[1].trimmed().toInt(&ok);
if (ok) {
param = parsedParam;
}
}
LOG_INFO("收到start命令参数: %d\n", param);
// 保存当前请求的客户端
{
QMutexLocker locker(&m_mutex);
m_pCurrentClient = pClient;
}
// 触发检测回调
if (m_detectionCallback) {
bool success = m_detectionCallback(param);
if (!success) {
LOG_ERROR("触发检测失败\n");
// 可以选择发送错误响应
}
} else {
LOG_WARNING("检测回调未设置\n");
}
} else {
LOG_WARNING("未知命令: %s\n", cmd.toStdString().c_str());
}
}
bool WheelMeasureTCPProtocol::SendData(const TCPClient* pClient, const QString& data)
{
if (!m_pTCPServer || !m_bServerRunning) {
return false;
}
QByteArray byteArray = data.toUtf8();
if (pClient) {
// 发送给指定客户端
return m_pTCPServer->SendData(pClient, byteArray.constData(), byteArray.size());
} else {
// 发送给所有客户端
return m_pTCPServer->SendAllData(byteArray.constData(), byteArray.size());
}
}