255 lines
7.6 KiB
C++
255 lines
7.6 KiB
C++
|
|
#include "BeltTearingPresenter.h"
|
|||
|
|
#include "VrTcpClient.h"
|
|||
|
|
#include "PathManager.h"
|
|||
|
|
#include "VrLog.h"
|
|||
|
|
#include <QDebug>
|
|||
|
|
#include <QTimer>
|
|||
|
|
#include <QImage>
|
|||
|
|
#include <QBuffer>
|
|||
|
|
#include <QVariant>
|
|||
|
|
#include <QSettings>
|
|||
|
|
#include <QDir>
|
|||
|
|
#include "widgets/DeviceStatusWidget.h"
|
|||
|
|
#include "VrDateUtils.h"
|
|||
|
|
|
|||
|
|
BeltTearingPresenter::BeltTearingPresenter(QWidget* parent)
|
|||
|
|
: QWidget(parent)
|
|||
|
|
, m_config(nullptr)
|
|||
|
|
{
|
|||
|
|
// 创建配置实例
|
|||
|
|
IVrBeltTearingConfig::CreateInstance(&m_config);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
BeltTearingPresenter::~BeltTearingPresenter()
|
|||
|
|
{
|
|||
|
|
disconnectFromServer();
|
|||
|
|
|
|||
|
|
// 删除所有TCP客户端
|
|||
|
|
for (auto it = m_tcpClients.begin(); it != m_tcpClients.end(); ++it) {
|
|||
|
|
delete it.value();
|
|||
|
|
}
|
|||
|
|
m_tcpClients.clear();
|
|||
|
|
|
|||
|
|
if (m_config) {
|
|||
|
|
delete m_config;
|
|||
|
|
m_config = nullptr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::Init()
|
|||
|
|
{
|
|||
|
|
QString configPath = PathManager::GetConfigFilePath();
|
|||
|
|
initializeConfig(configPath);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool BeltTearingPresenter::initializeConfig(const QString &configPath)
|
|||
|
|
{
|
|||
|
|
if (!m_config) {
|
|||
|
|
LOG_WARNING("Config instance is null");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
BeltTearingConfigResult configResult = m_config->LoadConfig(configPath.toStdString());
|
|||
|
|
if (configResult.servers.empty()) {
|
|||
|
|
LOG_WARNING("Failed to load config from: %s", configPath.toStdString().c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取所有服务器配置
|
|||
|
|
const auto &servers = configResult.servers;
|
|||
|
|
if (servers.empty()) {
|
|||
|
|
LOG_WARNING("No servers configured");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清空现有配置
|
|||
|
|
m_serverInfos.clear();
|
|||
|
|
|
|||
|
|
// 存储所有启用的服务器信息
|
|||
|
|
QList<DeviceInfo> devices;
|
|||
|
|
for (const auto &server : servers) {
|
|||
|
|
QString serverName = QString("%1_%2").arg(QString::fromStdString(server.name)).arg(CVrDateUtils::GetTimestamp());
|
|||
|
|
m_serverInfos[serverName] = server;
|
|||
|
|
|
|||
|
|
bool bRet = connectToServer(server, serverName);
|
|||
|
|
if(!bRet) continue;
|
|||
|
|
|
|||
|
|
// 添加到设备列表
|
|||
|
|
devices.append(DeviceInfo(QString::fromStdString(server.name), serverName, QString::fromStdString(server.ip), DeviceStatus::Offline, true));
|
|||
|
|
LOG_DEBUG("Server configured: %s %s:%d \n", serverName.toStdString().c_str(), server.ip.c_str(), server.port);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (m_serverInfos.empty()) {
|
|||
|
|
LOG_WARNING("No enabled servers found");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
LOG_DEBUG("Config loaded successfully. Found %d enabled servers", m_serverInfos.size());
|
|||
|
|
|
|||
|
|
// 更新设备状态控件的设备列表
|
|||
|
|
if (m_deviceStatusWidget) {
|
|||
|
|
m_deviceStatusWidget->setDevices(devices);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool BeltTearingPresenter::connectToServer(const ServerInfo &serverInfo, const QString &serverName)
|
|||
|
|
{
|
|||
|
|
QString targetServerName = serverName;
|
|||
|
|
|
|||
|
|
// 创建TCP客户端(如果不存在)
|
|||
|
|
if (!m_tcpClients.contains(targetServerName)) {
|
|||
|
|
VrTcpClient *client = new VrTcpClient();
|
|||
|
|
m_tcpClients[targetServerName] = client;
|
|||
|
|
|
|||
|
|
// 连接TCP客户端的信号到Presenter的槽函数
|
|||
|
|
connect(client, &IVrTcpClient::connected, this, [this, targetServerName]() {
|
|||
|
|
onConnected(targetServerName);
|
|||
|
|
});
|
|||
|
|
connect(client, &IVrTcpClient::disconnected, this, [this, targetServerName]() {
|
|||
|
|
onDisconnected(targetServerName);
|
|||
|
|
});
|
|||
|
|
connect(client, &IVrTcpClient::connectionError, this, [this, targetServerName](const QString &error) {
|
|||
|
|
onTcpError(targetServerName, error);
|
|||
|
|
});
|
|||
|
|
connect(client, &IVrTcpClient::dataReceived, this, [this, targetServerName](const QByteArray &data) {
|
|||
|
|
onDataReceived(targetServerName, data);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
VrTcpClient *client = m_tcpClients[targetServerName];
|
|||
|
|
|
|||
|
|
// 设置自动重连
|
|||
|
|
client->setAutoReconnect(true);
|
|||
|
|
client->setReconnectInterval(5000); // 5秒重连间隔
|
|||
|
|
|
|||
|
|
// 连接服务器
|
|||
|
|
bool success = client->connectToServer(QString::fromStdString(serverInfo.ip), serverInfo.port);
|
|||
|
|
|
|||
|
|
if (!success) {
|
|||
|
|
LOG_ERROR("Failed to initiate connection to %s", targetServerName.toStdString().c_str());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return success;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::disconnectFromServer(const QString &serverName)
|
|||
|
|
{
|
|||
|
|
if (serverName.isEmpty()) {
|
|||
|
|
// 断开所有连接
|
|||
|
|
for (auto it = m_tcpClients.begin(); it != m_tcpClients.end(); ++it) {
|
|||
|
|
if (it.value()->isConnected()) {
|
|||
|
|
it.value()->disconnectFromServer();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 断开指定服务器连接
|
|||
|
|
if (m_tcpClients.contains(serverName) && m_tcpClients[serverName]->isConnected()) {
|
|||
|
|
m_tcpClients[serverName]->disconnectFromServer();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool BeltTearingPresenter::isConnected(const QString &serverName) const
|
|||
|
|
{
|
|||
|
|
if(serverName.isEmpty()) return false;
|
|||
|
|
|
|||
|
|
QString targetServerName = serverName;
|
|||
|
|
|
|||
|
|
if (m_tcpClients.contains(targetServerName)) {
|
|||
|
|
return m_tcpClients[targetServerName]->isConnected();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool BeltTearingPresenter::sendData(const QByteArray &data, const QString &serverName)
|
|||
|
|
{
|
|||
|
|
if(serverName.isEmpty()) return false;
|
|||
|
|
QString targetServerName = serverName;
|
|||
|
|
|
|||
|
|
if (!isConnected(targetServerName)) {
|
|||
|
|
LOG_ERROR("Not connected to server: %s", targetServerName.toStdString().c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (data.isEmpty()) {
|
|||
|
|
LOG_ERROR("Empty data to send");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!m_tcpClients.contains(targetServerName)) {
|
|||
|
|
LOG_ERROR("Server client not found: %s", targetServerName.toStdString().c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool success = m_tcpClients[targetServerName]->sendData(data);
|
|||
|
|
if (!success) {
|
|||
|
|
LOG_ERROR("Failed to send data to %s", targetServerName.toStdString().c_str());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return success;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QStringList BeltTearingPresenter::getServerNames() const
|
|||
|
|
{
|
|||
|
|
return m_serverInfos.keys();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString BeltTearingPresenter::getServerIp(const QString &serverName) const
|
|||
|
|
{
|
|||
|
|
if (m_serverInfos.contains(serverName)) {
|
|||
|
|
return QString::fromStdString(m_serverInfos[serverName].ip);
|
|||
|
|
}
|
|||
|
|
return QString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
quint16 BeltTearingPresenter::getServerPort(const QString &serverName) const
|
|||
|
|
{
|
|||
|
|
if (m_serverInfos.contains(serverName)) {
|
|||
|
|
return m_serverInfos[serverName].port;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString BeltTearingPresenter::getServerDisplayName(const QString &serverName) const
|
|||
|
|
{
|
|||
|
|
if (m_serverInfos.contains(serverName)) {
|
|||
|
|
return QString::fromStdString(m_serverInfos[serverName].name);
|
|||
|
|
}
|
|||
|
|
return QString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::onConnected(const QString &serverName)
|
|||
|
|
{
|
|||
|
|
// 更新设备状态为在线
|
|||
|
|
if (m_deviceStatusWidget) {
|
|||
|
|
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Online);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::onDisconnected(const QString &serverName)
|
|||
|
|
{
|
|||
|
|
// 更新设备状态为离线
|
|||
|
|
if (m_deviceStatusWidget) {
|
|||
|
|
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Offline);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::onDataReceived(const QString &serverName, const QByteArray &data)
|
|||
|
|
{
|
|||
|
|
// 尝试解析图像数据
|
|||
|
|
QImage image;
|
|||
|
|
if (image.loadFromData(data)) {
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BeltTearingPresenter::onTcpError(const QString &error, const QString &serverName)
|
|||
|
|
{
|
|||
|
|
if (m_deviceStatusWidget) {
|
|||
|
|
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|