用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_serverQWebSocketServer 对象,用于监听和处理客户端连接。
    • 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();
}
相关推荐
C语言魔术师3 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳1 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?1 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
桂月二二7 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
九酒9 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔10 小时前
HTML5 新表单属性详解
前端·html·html5
北顾南栀倾寒10 小时前
[Qt]系统相关-网络编程-TCP、UDP、HTTP协议
开发语言·网络·c++·qt·tcp/ip·http·udp