371 lines
11 KiB
C++
371 lines
11 KiB
C++
// CommunicationManager.cpp
|
||
#include "communicationManager.h"
|
||
#include <QDebug>
|
||
|
||
CommunicationManager* CommunicationManager::instance()
|
||
{
|
||
static CommunicationManager* instance = nullptr;
|
||
static QMutex mutex;
|
||
|
||
if (!instance) {
|
||
QMutexLocker locker(&mutex);
|
||
if (!instance) {
|
||
instance = new CommunicationManager;
|
||
}
|
||
}
|
||
return instance;
|
||
}
|
||
|
||
CommunicationManager::CommunicationManager(QObject* parent)
|
||
: QObject(parent)
|
||
{
|
||
// 设置默认配置
|
||
m_httpConfig.id = "http_channel";
|
||
m_httpConfig.name = "HTTP通道";
|
||
m_httpConfig.endpoint = "http://localhost:8080";
|
||
|
||
m_websocketConfig.id = "websocket_channel";
|
||
m_websocketConfig.name = "WebSocket通道";
|
||
m_websocketConfig.endpoint = "ws://localhost:8888/ws";
|
||
}
|
||
|
||
CommunicationManager::~CommunicationManager()
|
||
{
|
||
disconnectHttp();
|
||
disconnectWebSocket();
|
||
}
|
||
|
||
bool CommunicationManager::initialize()
|
||
{
|
||
// 初始化HTTP通道
|
||
initHttpChannel();
|
||
|
||
// 初始化WebSocket通道
|
||
//initWebSocketChannel();
|
||
|
||
qInfo() << "CommunicationManager initialized";
|
||
return true;
|
||
}
|
||
|
||
void CommunicationManager::initHttpChannel()
|
||
{
|
||
if (m_httpChannel) {
|
||
m_httpChannel->disconnect();
|
||
}
|
||
|
||
// 创建HTTP通道
|
||
HttpChannel::ChannelConfig httpConfig;
|
||
httpConfig.endpoint = QUrl(m_httpConfig.endpoint);
|
||
httpConfig.timeout = m_httpConfig.timeout;
|
||
|
||
m_httpChannel.reset(new HttpChannel(httpConfig));
|
||
|
||
// 设置认证
|
||
if (!m_httpConfig.username.isEmpty() && !m_httpConfig.password.isEmpty()) {
|
||
m_httpChannel->setBasicAuth(m_httpConfig.username, m_httpConfig.password);
|
||
}
|
||
|
||
// 设置HTTP头
|
||
for (auto it = m_httpConfig.headers.begin(); it != m_httpConfig.headers.end(); ++it) {
|
||
m_httpChannel->setHeader(it.key(), it.value().toString());
|
||
}
|
||
|
||
// 连接信号
|
||
connect(m_httpChannel.data(), &HttpChannel::connected,
|
||
this, &CommunicationManager::httpConnected);
|
||
connect(m_httpChannel.data(), &HttpChannel::disconnected,
|
||
this, &CommunicationManager::httpDisconnected);
|
||
connect(m_httpChannel.data(), &HttpChannel::dataReceived,
|
||
this, &CommunicationManager::httpDataReceived);
|
||
connect(m_httpChannel.data(), &HttpChannel::errorOccurred,
|
||
this, &CommunicationManager::httpError);
|
||
}
|
||
|
||
void CommunicationManager::initWebSocketChannel(QString sessionId)
|
||
{
|
||
WebSocketChannel::ChannelConfig wsConfig;
|
||
wsConfig.endpoint = QUrl(m_websocketConfig.endpoint);
|
||
wsConfig.timeout = m_websocketConfig.timeout;
|
||
|
||
WebSocketChannel::WebSocketConfig websocketConfig;
|
||
websocketConfig.heartbeatInterval = m_websocketConfig.heartbeatInterval;
|
||
|
||
if(sessionId.isEmpty()){ //没有指定会话,初始化已有channel
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
pChannel->disconnect();
|
||
pChannel.reset(new WebSocketChannel(wsConfig,pChannel->sessionId()));
|
||
pChannel->setWebSocketConfig(websocketConfig);
|
||
|
||
// 连接信号
|
||
connect(pChannel.data(), &WebSocketChannel::connected,
|
||
this, &CommunicationManager::websocketConnected);
|
||
connect(pChannel.data(), &WebSocketChannel::disconnected,
|
||
this, &CommunicationManager::websocketDisconnected);
|
||
connect(pChannel.data(), &WebSocketChannel::dataReceived,
|
||
this, &CommunicationManager::websocketDataReceived);
|
||
connect(pChannel.data(), &WebSocketChannel::errorOccurred,
|
||
this, &CommunicationManager::websocketError);
|
||
connect(pChannel.data(), &WebSocketChannel::textMessageReceived,
|
||
this, &CommunicationManager::websocketTextReceived);
|
||
}
|
||
}
|
||
else{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){ //已存在
|
||
pChannel->disconnect();
|
||
pChannel.reset(new WebSocketChannel(wsConfig,pChannel->sessionId()));
|
||
pChannel->setWebSocketConfig(websocketConfig);
|
||
|
||
// 连接信号
|
||
connect(pChannel.data(), &WebSocketChannel::connected,
|
||
this, &CommunicationManager::websocketConnected);
|
||
connect(pChannel.data(), &WebSocketChannel::disconnected,
|
||
this, &CommunicationManager::websocketDisconnected);
|
||
connect(pChannel.data(), &WebSocketChannel::dataReceived,
|
||
this, &CommunicationManager::websocketDataReceived);
|
||
connect(pChannel.data(), &WebSocketChannel::errorOccurred,
|
||
this, &CommunicationManager::websocketError);
|
||
connect(pChannel.data(), &WebSocketChannel::textMessageReceived,
|
||
this, &CommunicationManager::websocketTextReceived);
|
||
return;
|
||
}
|
||
}
|
||
|
||
QSharedPointer<WebSocketChannel> newChannel(new WebSocketChannel(wsConfig,sessionId));
|
||
newChannel->setWebSocketConfig(websocketConfig);
|
||
|
||
// 连接信号
|
||
connect(newChannel.data(), &WebSocketChannel::connected,
|
||
this, &CommunicationManager::websocketConnected);
|
||
connect(newChannel.data(), &WebSocketChannel::disconnected,
|
||
this, &CommunicationManager::websocketDisconnected);
|
||
connect(newChannel.data(), &WebSocketChannel::dataReceived,
|
||
this, &CommunicationManager::websocketDataReceived);
|
||
connect(newChannel.data(), &WebSocketChannel::errorOccurred,
|
||
this, &CommunicationManager::websocketError);
|
||
connect(newChannel.data(), &WebSocketChannel::textMessageReceived,
|
||
this, &CommunicationManager::websocketTextReceived);
|
||
m_websocketChannelMap.insert(sessionId,newChannel);
|
||
}
|
||
}
|
||
|
||
bool CommunicationManager::connectHttp()
|
||
{
|
||
if (!m_httpChannel) {
|
||
qWarning() << "HTTP channel not initialized";
|
||
return false;
|
||
}
|
||
|
||
if (m_httpChannel->isConnected()) {
|
||
return true;
|
||
}
|
||
|
||
return m_httpChannel->connect();
|
||
}
|
||
|
||
bool CommunicationManager::disconnectHttp()
|
||
{
|
||
if (!m_httpChannel) {
|
||
return false;
|
||
}
|
||
|
||
if (!m_httpChannel->isConnected()) {
|
||
return true;
|
||
}
|
||
|
||
return m_httpChannel->disconnect();
|
||
}
|
||
|
||
bool CommunicationManager::sendHttpRequest(const QString& path,
|
||
const QByteArray& data,
|
||
const QString& method,
|
||
const QVariantMap& query)
|
||
{
|
||
if (!m_httpChannel || !m_httpChannel->isConnected()) {
|
||
qWarning() << "HTTP channel not connected";
|
||
return false;
|
||
}
|
||
|
||
if (method == "GET") {
|
||
return m_httpChannel->get(path,query);
|
||
} else if (method == "POST") {
|
||
return m_httpChannel->post(data, path);
|
||
} else if (method == "PUT") {
|
||
return m_httpChannel->put(data, path);
|
||
} else if (method == "DELETE") {
|
||
return m_httpChannel->deleteResource(path);
|
||
}
|
||
|
||
qWarning() << "Unsupported HTTP method:" << method;
|
||
return false;
|
||
}
|
||
|
||
bool CommunicationManager::connectWebSocket(const QString& sessionId)
|
||
{
|
||
if(sessionId.isEmpty()){
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if (!pChannel->isConnected()) {
|
||
pChannel->connect();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if (pChannel->isConnected()) {
|
||
return true;
|
||
}
|
||
|
||
return pChannel->connect();
|
||
}
|
||
}
|
||
}
|
||
|
||
qWarning() << "WebSocket channel not initialized";
|
||
return false;
|
||
|
||
}
|
||
|
||
bool CommunicationManager::disconnectWebSocket(const QString& sessionId)
|
||
{
|
||
|
||
if(sessionId.isEmpty()){ //不指定则断开所有通道
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if (pChannel->isConnected()) {
|
||
pChannel->disconnect();
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
else{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if (!pChannel->isConnected()) {
|
||
return true;
|
||
}
|
||
|
||
return pChannel->disconnect();
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CommunicationManager::removeChannel(const QString& sessionId)
|
||
{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if (pChannel->isConnected()) {
|
||
pChannel->disconnect();
|
||
}
|
||
m_websocketChannelMap.remove(sessionId);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool CommunicationManager::sendWebSocketMessage(const QByteArray& data,const QString& sessionId)
|
||
{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if(!pChannel->isConnected()){
|
||
qWarning() << "WebSocket channel not connected";
|
||
return false;
|
||
}
|
||
|
||
return pChannel->send(data);
|
||
}
|
||
}
|
||
|
||
qWarning() << "WebSocket channel not connected";
|
||
return false;
|
||
}
|
||
|
||
bool CommunicationManager::sendWebSocketText(const QString& text,const QString& sessionId)
|
||
{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if(!pChannel->isConnected()){
|
||
qWarning() << "WebSocket channel not connected";
|
||
return false;
|
||
}
|
||
|
||
return pChannel->sendText(text);
|
||
}
|
||
}
|
||
|
||
qWarning() << "WebSocket channel not connected";
|
||
return false;
|
||
}
|
||
|
||
bool CommunicationManager::isHttpConnected() const
|
||
{
|
||
return m_httpChannel && m_httpChannel->isConnected();
|
||
}
|
||
|
||
bool CommunicationManager::isWebSocketConnected(const QString& sessionId) const
|
||
{
|
||
for(auto& pChannel:m_websocketChannelMap){
|
||
if(pChannel->sessionId() == sessionId){
|
||
if(pChannel->isConnected()){
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
ChannelConfig CommunicationManager::getHttpConfig() const
|
||
{
|
||
return m_httpConfig;
|
||
}
|
||
|
||
ChannelConfig CommunicationManager::getWebSocketConfig() const
|
||
{
|
||
return m_websocketConfig;
|
||
}
|
||
|
||
void CommunicationManager::updateHttpConfig(const ChannelConfig& config)
|
||
{
|
||
bool reconnect = false;
|
||
|
||
if (m_httpConfig.endpoint != config.endpoint) {
|
||
// 端点变化,需要重新初始化
|
||
reconnect = true;
|
||
}
|
||
|
||
m_httpConfig = config;
|
||
initHttpChannel();
|
||
|
||
if (reconnect && config.autoConnect) {
|
||
connectHttp();
|
||
}
|
||
|
||
qInfo() << "HTTP config updated";
|
||
}
|
||
|
||
void CommunicationManager::updateWebSocketConfig(const ChannelConfig& config,const QString& sessionId)
|
||
{
|
||
bool reconnect = false;
|
||
|
||
if (m_websocketConfig.endpoint != config.endpoint) {
|
||
reconnect = true;
|
||
}
|
||
|
||
m_websocketConfig = config;
|
||
initWebSocketChannel(sessionId);
|
||
|
||
if (reconnect && config.autoConnect) {
|
||
connectWebSocket(sessionId);
|
||
}
|
||
|
||
qInfo() << "WebSocket config updated";
|
||
}
|