Windows11下 Visual Studio 2022 + Qt6 的 WebSocket 线程池异步 客户端
- 1 开发 WebSocket 客户端
- 1.1 开发环境
- 1.1.1 为Qt 6安装 websockets
- 1.2 .基于Qt6的 QWebSocket 客户端示例
- 1.2.1 实现 WebSocket 客户端
- 1.2.2 创建 QtQWesocketClient
- 1.2.3 创建QWebsocket对象
- 1.2.3.1 添加 QtClientWebsocketBase 基类
- 1.2.3.2 改造 QtClientWebsocketBase 基类
- 1.2.3.3 创建 QWebSocket 对象,连接其相关的信号和槽
- 1.2.3.4 在链接器中增加 QWebSocket(Qt6WebSockets.lib)和Qt网络模块(Qt6Network.lib)
- 2 多线程 websocket
- 2.1 从QtClientWebsocketBase派生一个类 QtClientWorker
- 2.2 moveToThread QtClientWorker 对象
1 开发 WebSocket 客户端
今天我们来开发一个结程池异步的WebSocket客户端,WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,相信大家都有一些了解,我就不多介绍了。
1.1 开发环境
Windows 11 + Visual Studio 2022 + Qt6,Websocket采用的是 Qt6提供的QWebSocket(Qt6WebSockets.lib),他是Qt网络模块(Qt6Network.lib)的一部分,提供了对WebSocket协议的支持。
1.1.1 为Qt 6安装 websockets
如在安装QT时没有安装 websockets 库,后面会找不到需要的头文件,这里我以Windows 11版本来说明为 Qt6 安装 websockets。在控制面板中,选中程序和功能,在卸载或更改程序中选中“QT”,在维护Qt里选择 添加或移除组件。
在对应的QT版本的目录下找到Qt WebSockets进行安装。
1.2 .基于Qt6的 QWebSocket 客户端示例
1.2.1 实现 WebSocket 客户端
我们来看客户端实现的步骤。
步骤 | 说明 |
---|---|
建立连接 | WebSocket 客户端首先通过 WebSocket URL(ws:// 或 wss://)来连接到服务器,与服务端建立连接。 |
发送和接收数据 | 连接建立成功后,客 WebSocket户端通过发送和接收消息来和服务端交换数据。 |
处理事件 | WebSocket 客户端可以监听连接状态、错误和消息等事件,并根据需要处理这些事件。 |
关闭连接 | 在交换数据任务完成后, WebSocket 客户端应该友好关闭 WebSocket 连接,释放资源。 |
1.2.2 创建 QtQWesocketClient
在Qt6中创建一个 Qt Widgets Application 新项目 QtQWesocketClient 来开发QWebSocket 客户端
1.2.3 创建QWebsocket对象
1.2.3.1 添加 QtClientWebsocketBase 基类
我们在 QtQWesocketClient 项目中添加一个 QtClientWebsocketBase 基类,用来创建QWebSocket,并连接其相关的信号和槽。
1.2.3.2 改造 QtClientWebsocketBase 基类
Visual Studio 2022 和 Qt6的环境还不是太完善,生成的类和我们需要的有挺大差异,我们来改造下,代码如下:
// QtClientWebsocketBase.h
#include <qobject>class QtClientWebsocketBase : public QObject
{Q_OBJECTpublic:explicit QtClientWebsocketBase(QObject* parent);~QtClientWebsocketBase();
};
// QtClientWebsocketBase.cpp
#include "QtClientWebsocketBase.h"QtClientWebsocketBase::QtClientWebsocketBase(QObject* parent) : QObject(parent)
{
}QtClientWebsocketBase::~QtClientWebsocketBase()
{
}
1.2.3.3 创建 QWebSocket 对象,连接其相关的信号和槽
- 当连接成功时,connected() 信号会被触发,我们通过 connect(m_pWebSocket, SIGNAL(connected()), this, SLOT(slotConnected())); 将信号 connected 和槽函数 slotConnected 连接起来;
- 当连接断开时,disconnected() 信号会被触发,我们通过 connect(m_pWebSocket, SIGNAL(disconnected()), this, SLOT(slotDisconnected())); 将信号 disconnected 和槽函数 slotDisconnected 连接起来;
- 当连接出错时,error() 信号会被触发,我们通过 connect(m_pWebSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotError(QAbstractSocket::SocketError))); 将信号 error() 和槽函数 slotError连接起来;
- 当接收到服务端文本消息时,textMessageReceived() 信号会被触发,我们通过 connect(m_pWebSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(slotRecvTextMsg(QString))); 将 textMessageReceived() 信号 和槽函数slotRecvTextMsg 连接起来;
- 当接收到服务端二进制消息时,binaryMessageReceived() 信号会被触发,我们通过 connect(m_pWebSocket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(slotRecvBinaryMsg(QByteArray)));将 binaryMessageReceived() 信号 和槽函数 slotRecvBinaryMsg 连接起来。
#pragma once#include <QObject>
#include <QDebug>
#include <QUrl>
#include <QSettings>
#include <QtNetwork/qabstractsocket.h>
#include <QtWebSockets/qwebsocket.h>class QClientWebSocketBase : public QObject
{Q_OBJECTpublic:explicit QClientWebSocketBase(QObject* parent);~QClientWebSocketBase();private:void setSslConfiguation(); // 设置wss连接的SSL配置public:void connectUrl(QString ip, qint32 port, bool enableSsl); // 连接websocket服务器的URLvoid close(); // 关闭websocketvoid sendTextMsg(const QString& message); // 发送Text类型的消息void sendBinaryMsg(const QByteArray& data); // 发送Binary类型的消息bool getConnectStatus(