1. 重构了WebSocket类的实现,并且设置其为项目的核心通信协议

This commit is contained in:
Misaki
2025-12-30 04:59:03 +08:00
parent 702b083e47
commit bb509e5409
10 changed files with 1225 additions and 280 deletions
+118
View File
@@ -0,0 +1,118 @@
//
// Created by misaki on 2025/12/29.
//
#include "NetWorkDO.h"
#include <QDebug>
#include <QMutexLocker>
// 初始化静态成员
QScopedPointer<NetworkDO> NetworkDO::m_instance;
QMutex NetworkDO::m_mutex;
// 单例实现 (QScopedPointer + Mutex)
NetworkDO* NetworkDO::getInstance()
{
if (m_instance.isNull()) {
QMutexLocker locker(&m_mutex);
if (m_instance.isNull()) {
// 使用 reset 创建实例,因为构造函数是私有的
m_instance.reset(new NetworkDO());
}
}
return m_instance.data();
}
void NetworkDO::destroy()
{
QMutexLocker locker(&m_mutex);
if (!m_instance.isNull()) {
m_instance.reset(); // 这会触发析构函数
}
}
NetworkDO::NetworkDO(QObject *parent) : QObject(parent)
{
qDebug() << "NetworkDO initialized";
}
NetworkDO::~NetworkDO()
{
qDebug() << "NetworkDO destroyed";
}
// 业务逻辑实现
void NetworkDO::registerSender(SenderFunc sender)
{
QMutexLocker locker(&m_mutex); // 简单保护一下赋值
m_sender = std::move(sender);
}
void NetworkDO::sendAudioPacket(const AudioDataPacket& packet)
{
// 检查发送器是否已注入
if (!m_sender) {
emit errorOccurred("Sender not registered! Call registerSender() first.");
return;
}
// 封装数据 (DTO -> JSON)
QJsonObject dataObj;
dataObj["text"] = packet.text;
// 音频转 Base64 字符串传输
dataObj["audio"] = QString::fromLatin1(packet.audioData.toBase64());
dataObj["sampleRate"] = packet.sampleRate;
dataObj["channels"] = packet.channels;
dataObj["duration"] = packet.duration;
// 调用底层发送 (解耦)
// "textAudio" 是与后端约定的协议类型
m_sender("textAudio", dataObj);
}
void NetworkDO::sendControlPacket(const ControlDataPacket& packet)
{
if (!m_sender) return;
QJsonObject dataObj;
dataObj["action"] = static_cast<int>(packet.action);
dataObj["x"] = packet.x;
dataObj["y"] = packet.y;
m_sender("control", dataObj);
}
void NetworkDO::onDataReceived(const QString& type, const QJsonObject& data)
{
// 根据类型分发
if (type == "textAudio") {
handleAudioMessage(data);
}
else if (type == "control") {
// handleControlMessage(data);
}
else {
qWarning() << "[NetworkDO] Received unknown type:" << type;
}
}
void NetworkDO::handleAudioMessage(const QJsonObject& data)
{
AudioDataPacket packet;
// 解析基础字段 (JSON -> DTO)
packet.text = data.value("text").toString();
packet.sampleRate = data.value("sampleRate").toInt(16000);
packet.channels = data.value("channels").toInt(1);
// 注意类型转换,确保 long long 精度
packet.duration = static_cast<qint64>(data.value("duration").toDouble());
// 解析音频 (Base64 -> Binary)
QString base64Audio = data.value("audio").toString();
if (!base64Audio.isEmpty()) {
packet.audioData = QByteArray::fromBase64(base64Audio.toLatin1());
}
// 通知上层业务
emit audioPacketReceived(packet);
}