1、概述
QWebSocket
是Qt网络模块中的一个类,用于实现WebSocket协议的通信。WebSocket是一种全双工的通信协议,允许在客户端和服务器之间建立实时的双向通信。QWebSocket
提供了对WebSocket协议的支持,使得开发者能够在Qt应用中方便地实现实时通信功能。它在需要实时数据传输、消息推送等场景中非常常见,如聊天室、实时数据流、在线游戏等
2、重要方法
QWebSocket(const QString &origin = QString(), QWebSocketProtocol::Version version = QWebSocketProtocol::VersionLatest, QObject *parent = nullptr)
:构造函数,用于创建一个QWebSocket
对象。origin
参数指定了WebSocket连接的来源,version
参数指定了WebSocket协议的版本,parent
参数指定了父对象。virtual ~QWebSocket() override
:析构函数,用于销毁QWebSocket
对象。void abort()
:立即关闭WebSocket连接,不发送关闭帧。qint64 bytesToWrite() const
:返回待发送的字节数。QWebSocketProtocol::CloseCode closeCode() const
:返回WebSocket连接关闭的原因代码。QString closeReason() const
:返回WebSocket连接关闭的原因文本。QAbstractSocket::SocketError error() const
:返回最近一次发生的错误类型。QString errorString() const
:返回最近一次错误的描述信息。bool flush()
:尝试将所有待发送的数据发送出去。void ignoreSslErrors(const QList<QSslError> &errors)
:忽略指定的SSL错误。bool isValid() const
:检查WebSocket连接是否有效。QHostAddress localAddress() const
:返回本机的IP地址。quint16 localPort() const
:返回本机的端口号。const QMaskGenerator *maskGenerator() const
:返回当前使用的掩码生成器。QString origin() const
:返回WebSocket连接的来源。QAbstractSocket::PauseModes pauseMode() const
:返回当前的暂停模式。QHostAddress peerAddress() const
:返回对端的IP地址。QString peerName() const
:返回对端的主机名。quint16 peerPort() const
:返回对端的端口号。QNetworkProxy proxy() const
:返回当前使用的代理。qint64 readBufferSize() const
:返回读取缓冲区的大小。QNetworkRequest request() const
:返回当前的网络请求。QUrl requestUrl() const
:返回请求的URL。QString resourceName() const
:返回资源名称。void resume()
:恢复暂停的连接。qint64 sendBinaryMessage(const QByteArray &data)
:发送一个二进制消息。qint64 sendTextMessage(const QString &message)
:发送一个文本消息。void setMaskGenerator(const QMaskGenerator *maskGenerator)
:设置掩码生成器。void setPauseMode(QAbstractSocket::PauseModes pauseMode)
:设置暂停模式。void setProxy(const QNetworkProxy &networkProxy)
:设置代理。void setReadBufferSize(qint64 size)
:设置读取缓冲区的大小。void setSslConfiguration(const QSslConfiguration &sslConfiguration)
:设置SSL配置。QSslConfiguration sslConfiguration() const
:返回当前的SSL配置。QAbstractSocket::SocketState state() const
:返回当前的连接状态。QWebSocketProtocol::Version version() const
:返回当前使用的WebSocket协议版本。
void close(QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CloseCodeNormal, const QString &reason = QString())
:关闭WebSocket连接,可以指定关闭代码和原因。void ignoreSslErrors()
:忽略所有SSL错误。void open(const QNetworkRequest &request)
:使用QNetworkRequest
打开WebSocket连接。void open(const QUrl &url)
:使用URL打开WebSocket连接。void ping(const QByteArray &payload = QByteArray())
:发送一个Ping帧,可选地携带负载。
3、信号
void aboutToClose()
:即将关闭连接时发出。void binaryFrameReceived(const QByteArray &frame, bool isLastFrame)
:收到二进制帧时发出。void binaryMessageReceived(const QByteArray &message)
:收到二进制消息时发出。void bytesWritten(qint64 bytes)
:成功写入字节时发出。void connected()
:连接成功时发出。void disconnected()
:连接断开时发出。void error(QAbstractSocket::SocketError error)
:发生错误时发出。void pong(quint64 elapsedTime, const QByteArray &payload)
:收到Pong响应时发出。void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
:需要预共享密钥认证时发出。void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
:需要代理认证时发出。void readChannelFinished()
:读取通道关闭时发出。void sslErrors(const QList<QSslError> &errors)
:SSL错误发生时发出。void stateChanged(QAbstractSocket::SocketState state)
:连接状态改变时发出。void textFrameReceived(const QString &frame, bool isLastFrame)
:收到文本帧时发出。void textMessageReceived(const QString &message)
:收到文本消息时发出。
4、实例
//.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDir>
#include <iomanip>
#include <sstream>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
#include <QDebug>
#include <QWebSocketServer>
#include <QtWebSockets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
//server
QWebSocketServer* m_server = nullptr;
QList<QWebSocket*> m_clients;
//client
QWebSocket m_client;
public slots:
void on_disconnected();
void on_textMessageReceived(const QString &message);
void connected();
void disconnected();
void textMessageReceived(const QString &message);
private slots:
void on_pushButton_5_clicked();
void on_pushButton_6_clicked();
void on_pushButton_2_clicked();
void on_pushButton_clicked();
void on_newConnection(); // 有新的客户端连接
void on_closed(); // 关闭监听成功
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QPushButton>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("WebSocket");
m_server = new QWebSocketServer("web服务端", QWebSocketServer::NonSecureMode, this);
connect(m_server, &QWebSocketServer::newConnection, this, &MainWindow::on_newConnection);
connect(m_server, &QWebSocketServer::closed, this, &MainWindow::on_closed);
connect(&m_client, &QWebSocket::connected, this, &MainWindow::connected);
connect(&m_client, &QWebSocket::textFrameReceived, this, &MainWindow::textMessageReceived);
connect(&m_client, &QWebSocket::disconnected, this, &MainWindow::disconnected);
}
MainWindow::~MainWindow()
{
delete ui;
}
/**
* @brief 有新的客户端发起连接
*/
void MainWindow::on_newConnection()
{
QWebSocket* client = m_server->nextPendingConnection(); // 获取连接成功的客户端
connect(client, &QWebSocket::textMessageReceived, this, &MainWindow::on_textMessageReceived);
connect(client, &QWebSocket::disconnected, this, &MainWindow::on_disconnected);
// 将所有客户端加入列表
m_clients << client;
ui->textEdit_3->append(QString("[%1:%2] 连接成功!").arg(client->peerAddress().toString()).arg(client->peerPort()));
}
/**
* @brief 服务端关闭监听,关闭后不再接收新的客户端的连接请求
*/
void MainWindow::on_closed()
{
ui->textEdit->append("服务端关闭监听!");
ui->pushButton_5->setText("开启监听");
}
void MainWindow::on_pushButton_5_clicked()
{
//TcpServer::get()->startServer(ui->lineEdit_5->text().toInt());
if(!m_server->isListening())
{
bool ret = m_server->listen(QHostAddress::AnyIPv4, ui->lineEdit_5->text().toInt());
if(ret)
{
ui->textEdit_3->append(QString("开始监听:%1").arg(m_server->serverUrl().toString()));
ui->pushButton_5->setText("停止");
}
}
else
{
m_server->close();
}
}
/**
* @brief 向所有连接的客户端发送数据
*/
void MainWindow::on_pushButton_6_clicked()
{
QString data = ui->textEdit_4->toPlainText();
for(auto client : m_clients)
{
client->sendTextMessage(data);
}
}
/**
* @brief 断开连接时移除对应的客户端
*/
void MainWindow::on_disconnected()
{
QWebSocket *socket = qobject_cast<QWebSocket *>(sender());
for(int i = 0; i < m_clients.count(); ++i)
{
if(m_clients.at(i) == socket)
{
disconnect(socket, &QWebSocket::textMessageReceived, this, &MainWindow::on_textMessageReceived);
disconnect(socket, &QWebSocket::disconnected, this, &MainWindow::on_disconnected);
m_clients.removeAt(i);
break;
}
}
ui->textEdit->append(QString("[%1:%2] 断开连接!").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
}
/**
* @brief 接收信息并将信息转发给所有客户端
* @param message
*/
void MainWindow::on_textMessageReceived(const QString &message)
{
QWebSocket *socket = qobject_cast<QWebSocket *>(sender());
for(auto client : m_clients)
{
if(client != socket) // 向所有连接的客户端转发信息,除了当前信息的发出者
{
client->sendTextMessage(message);
}
}
ui->textEdit_3->append(QString("[%1:%2] %3").arg(socket->peerAddress().toString()).arg(socket->peerPort()).arg(message));
}
void MainWindow::connected()
{
ui->textEdit_2->append("连接成功!");
}
void MainWindow::disconnected()
{
ui->textEdit_2->append("断开连接!");
}
/**
* @brief 接收数据
* @param message
*/
void MainWindow::textMessageReceived(const QString &message)
{
ui->textEdit_2->append(message);
}
void MainWindow::on_pushButton_2_clicked()
{
m_client.open(QUrl(ui->lineEdit->text().trimmed()));
}
void MainWindow::on_pushButton_clicked()
{
QString data = ui->textEdit->toPlainText();
if(m_client.state() == QAbstractSocket::ConnectedState) // 判断是否连接
{
m_client.sendTextMessage(data);
}
}
源码下载:点击跳转
觉得有帮助的话,打赏一下呗。。