当前位置: 首页 > article >正文

用QWebSocketServer写websocket服务端

1. 引入必要的头文件

#include <QCoreApplication>
#include <QWebSocketServer>
#include <QWebSocket>
#include <QDebug>
#include <QObject>
  • QCoreApplication:用于创建控制台应用的事件循环。
  • QWebSocketServer:提供 WebSocket 服务端的接口,用于监听和管理客户端连接。
  • QWebSocket:表示每个客户端连接的 WebSocket 通道。
  • QDebug:用于输出调试信息。
  • QObject:所有 Qt 对象的基类,提供信号和槽机制。

2. 定义 WebSocketServer 类 

class WebSocketServer : public QObject
{
    Q_OBJECT

public:
    WebSocketServer(quint16 port, QObject *parent = nullptr);
    ~WebSocketServer();

private slots:
    void onNewConnection();
    void onTextMessageReceived(const QString &message);
    void onClientDisconnected();
    void onClosed();

private:
    QWebSocketServer *m_server;
    QList<QWebSocket *> m_clients;
};
  • WebSocketServer 类:自定义的 WebSocket 服务端类,继承自 QObject
  • 构造函数:接受一个端口号,创建并启动 WebSocket 服务端。
  • 析构函数:关闭服务端并清理所有客户端连接。
  • 槽函数:用于处理新连接、接收消息、客户端断开连接、和服务端关闭的事件。
  • 私有成员变量
    • m_serverQWebSocketServer 对象,用于监听和处理客户端连接。
    • m_clients:存储所有连接的客户端。

3. 构造函数和析构函数 

WebSocketServer::WebSocketServer(quint16 port, QObject *parent)
    : QObject(parent), m_server(new QWebSocketServer(QStringLiteral("Echo Server"),
                                                     QWebSocketServer::NonSecureMode, this))
{
    if (m_server->listen(QHostAddress::Any, port)) {
        qDebug() << "WebSocket server listening on port" << port;
        connect(m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onNewConnection);
        connect(m_server, &QWebSocketServer::closed, this, &WebSocketServer::onClosed);
    }
}

WebSocketServer::~WebSocketServer() {
    m_server->close();
    qDeleteAll(m_clients.begin(), m_clients.end());
}
  • 构造函数:启动服务端监听指定的端口,并连接 newConnection 信号(处理新客户端连接)和 closed 信号(处理服务端关闭)。
  • 析构函数:关闭服务端并清理所有客户端连接,以确保内存不会泄漏。

4. 处理新客户端连接

void WebSocketServer::onNewConnection() {
    QWebSocket *client = m_server->nextPendingConnection();
    connect(client, &QWebSocket::textMessageReceived, this, &WebSocketServer::onTextMessageReceived);
    connect(client, &QWebSocket::disconnected, this, &WebSocketServer::onClientDisconnected);
    m_clients << client;
    qDebug() << "New client connected";
}

 onNewConnection:在 newConnection 信号触发时调用,处理新的客户端连接。

  • 获取新连接的 QWebSocket 对象。
  • 将新客户端的 textMessageReceived 信号连接到 onTextMessageReceived 槽函数,用于处理客户端发送的消息。
  • disconnected 信号连接到 onClientDisconnected 槽函数,用于清理断开的客户端。
  • 将新连接添加到客户端列表 m_clients 中,方便后续管理。

5. 处理客户端消息 

void WebSocketServer::onTextMessageReceived(const QString &message) {
    QWebSocket *senderClient = qobject_cast<QWebSocket *>(sender());
    if (senderClient) {
        qDebug() << "Message received:" << message;
        senderClient->sendTextMessage("Echo: " + message);
    }
}

onTextMessageReceived:当客户端发送文本消息时被调用。

  • sender() 获取发送该信号的客户端对象,将其转换为 QWebSocket 类型。
  • 输出接收到的消息,并将其回显给客户端。

 6. 处理客户端断开连接

void WebSocketServer::onClientDisconnected() {
    QWebSocket *client = qobject_cast<QWebSocket *>(sender());
    if (client) {
        m_clients.removeAll(client);
        client->deleteLater();
        qDebug() << "Client disconnected";
    }
}

onClientDisconnected:在客户端断开连接时调用。

  • 获取断开连接的客户端对象,将其从 m_clients 列表中移除。
  • 调用 deleteLater() 延迟删除对象,释放其内存。

7. 处理服务端关闭 

void WebSocketServer::onClosed() {
    qDebug() << "Server closed";
}

 整体代码

 

#include <QCoreApplication>
#include <QWebSocketServer>
#include <QWebSocket>
#include <QDebug>
#include <QObject>

class WebSocketServer : public QObject
{
    Q_OBJECT

public:
    WebSocketServer(quint16 port, QObject *parent = nullptr) 
        : QObject(parent), m_server(new QWebSocketServer(QStringLiteral("Echo Server"),
                                                         QWebSocketServer::NonSecureMode, this))
    {
        if (m_server->listen(QHostAddress::Any, port)) {
            qDebug() << "WebSocket server listening on port" << port;
            connect(m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onNewConnection);
            connect(m_server, &QWebSocketServer::closed, this, &WebSocketServer::onClosed);
        }
    }

    ~WebSocketServer() {
        m_server->close();
        qDeleteAll(m_clients.begin(), m_clients.end());
    }

private slots:
    void onNewConnection() {
        QWebSocket *client = m_server->nextPendingConnection();
        connect(client, &QWebSocket::textMessageReceived, this, &WebSocketServer::onTextMessageReceived);
        connect(client, &QWebSocket::disconnected, this, &WebSocketServer::onClientDisconnected);
        m_clients << client;
        qDebug() << "New client connected";
    }

    void onTextMessageReceived(const QString &message) {
        QWebSocket *senderClient = qobject_cast<QWebSocket *>(sender());
        if (senderClient) {
            qDebug() << "Message received:" << message;
            senderClient->sendTextMessage("Echo: " + message);
        }
    }

    void onClientDisconnected() {
        QWebSocket *client = qobject_cast<QWebSocket *>(sender());
        if (client) {
            m_clients.removeAll(client);
            client->deleteLater();
            qDebug() << "Client disconnected";
        }
    }

    void onClosed() {
        qDebug() << "Server closed";
    }

private:
    QWebSocketServer *m_server;
    QList<QWebSocket *> m_clients;
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    WebSocketServer server(9000);
    return a.exec();
}

http://www.kler.cn/a/375608.html

相关文章:

  • Unity GameFramework Star Force 拆解(一)—— 启动流程
  • Pinpoint(APM)进阶--插件开发
  • Java中的线程安全问题(如果想知道Java中有关线程安全问题的基本知识,那么只看这一篇就足够了!)
  • Rust: 加密算法库 ring 如何用于 RSA 数字签名?
  • java项目中如何有效提高List集合的读写速度?
  • SpringBoot【实用篇】- 测试
  • 华为自研仓颉编程语言官网上线 首个公测版本开放下载
  • 基于GA遗传算法的悬索桥静载试验车辆最优布载matlab仿真
  • Minio 之 内网项目托管Unity Android包体
  • 个人开发三步走
  • wx.setNavigationBarColor动态设置导航栏颜色无效(亲测有效)
  • Hailo-8/8L系列汇总
  • 小白Git操作简洁步骤
  • PostgreSQL 增量备份:保护你的数据资产
  • ARKit读取LiDAR点云
  • qt QGroupBox详解
  • IO详解(BIO、NIO、实战案例、底层原理刨析)
  • CSS3简介(一)
  • 解决项目中图片出不来的bug
  • ubuntu启动慢,如何看启动耗时分布
  • 分布式 ID 生成策略(二)
  • Redis 内存回收策略小结
  • Spark中的常见算子
  • ubuntu22-安装vscode-配置shell命令环境-mac安装
  • Serverless + AI 让应用开发更简单
  • 报错:npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。