用QWebSocketServer写websocket服务端

  1. 引入必要的头文件
cpp 复制代码
#include <QCoreApplication>
#include <QWebSocketServer>
#include <QWebSocket>
#include <QDebug>
#include <QObject>
  • QCoreApplication:用于创建控制台应用的事件循环。
  • QWebSocketServer:提供 WebSocket 服务端的接口,用于监听和管理客户端连接。
  • QWebSocket:表示每个客户端连接的 WebSocket 通道。
  • QDebug:用于输出调试信息。
  • QObject:所有 Qt 对象的基类,提供信号和槽机制。
  1. 定义 WebSocketServer 类
cpp 复制代码
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_server :QWebSocketServer 对象,用于监听和处理客户端连接。
    • m_clients:存储所有连接的客户端。
  1. 构造函数和析构函数
cpp 复制代码
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 信号(处理服务端关闭)。
  • 析构函数:关闭服务端并清理所有客户端连接,以确保内存不会泄漏。
  1. 处理新客户端连接
cpp 复制代码
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 中,方便后续管理。
  1. 处理客户端消息
cpp 复制代码
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 类型。
  • 输出接收到的消息,并将其回显给客户端。
  1. 处理客户端断开连接
cpp 复制代码
void WebSocketServer::onClientDisconnected() {
    QWebSocket *client = qobject_cast<QWebSocket *>(sender());
    if (client) {
        m_clients.removeAll(client);
        client->deleteLater();
        qDebug() << "Client disconnected";
    }
}

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

  • 获取断开连接的客户端对象,将其从 m_clients 列表中移除。
  • 调用 deleteLater() 延迟删除对象,释放其内存。
  1. 处理服务端关闭
cpp 复制代码
void WebSocketServer::onClosed() {
    qDebug() << "Server closed";
}

整体代码

cpp 复制代码
#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();
}
相关推荐
qq_401700413 小时前
Qt 串口/网口通信:Hex 与 ASCII 编码转换深度指南
开发语言·数据库·qt
htzyl2063 小时前
前端阶梯——第九章、颜色、文本与背景
前端·css
zhangzeyuaaa4 小时前
Ruby `require` 完全指南:从 `$LOAD_PATH` 到 `require_relative`
服务器·前端·ruby
htzyl2064 小时前
前端阶梯——第八章、CSS入门与选择器
前端·css
猪猪拆迁队4 小时前
跨电脑复制共享-WebRTC 打洞踩坑
前端·后端·go
Amos_Web4 小时前
Rspack 源码解析(十八):Tree Shaking 如何用 SideEffects 重写模块连接
前端·rust·前端框架
百度一下吧4 小时前
前端包管理工具和使用手册
前端
anxiao_m5 小时前
水利数字孪生怎么选?主流可视化渲染平台深度横向测评
大数据·前端·人工智能·图形渲染·云渲染
kill5225 小时前
useRef
前端·javascript·react.js
蓝悦无人机5 小时前
从“摸形状“到“点到线面的距离“——聊聊 SLAM 前端(激光雷达篇)
前端·loam·数据关联·激光slam·点云特征提取·点到线面距离·icp/ndt