概 述
WebSockets 是一种通过单个 TCP 连接提供全双工通信信道的 web 技术。2011年,IETF 将 WebSocket 协议标准化为 RFC 6455 。Qt 提供的 QWebSocket 既可以用于客户端应用程序,也可以用于服务端应用程序,接口大部分和 QTcpSocket 一致。
QWebSocket 当前不支持 WebSocket 扩展和 WebSocket 子协议,仅支持 WebSocket 协议的版本13 (如 RFC 6455 中所述)。
QWebSocketServer的基本使用
要使用 Qt 的 WebSocket 模块,先在 pro 文件中加上 websockets:
QT += websockets
运行界面如下:
创建QWebSocketServer 对象创建
m_WebSocketServer = new QWebSocketServer(u8"server", QWebSocketServer::NonSecureMode);
启动webSocketServer 的监听
请在监听客户端连接事件响应。
if (m_WebSocketServer->listen(QHostAddress(ip), port.toInt()))
{
ui.textEdit_RecvMsg->append(u8"服务开启成功");
ui.btnOpenServer->setEnabled(false);
connect(m_WebSocketServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
else
{
QMessageBox::information(this, u8"提示", u8"监听失败, 是否开启了代理,或者IP错误");
}
客户端连接后响应函数处理
void WebsocketServerDemo::onNewConnection()
{
pSocket = m_WebSocketServer->nextPendingConnection();
m_clients << pSocket;
connect(pSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(processTextMessage(QString)));
connect(pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
QString peerName = pSocket->requestUrl().toString();
cout << "peerName = " << peerName.toStdString() << endl;
//将ip和socket保存到map
mapSocket[peerName] = pSocket;
ui.listWidget_OnlineUser->addItem(peerName);
}
消息处理函数
//处理接收到的消息
void WebsocketServerDemo::processTextMessage(QString message)
{
QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
QString item = pSocket->requestUrl().toString();
ui.textEdit_RecvMsg->append(time + "" + item + "\n" + message);
//处理消息转发
//...
}
客户端断开连接处理函数
//客户端连接断开的操作
void WebsocketServerDemo::socketDisconnected()
{
for (auto sk : m_clients)
{
if (!sk->isValid())
{
QString temp_key;
ui.textEdit_RecvMsg->append("map size = " + QString(mapSocket.size()) + "\n");
for (auto it = mapSocket.begin(); it!=mapSocket.end(); it++)
{
if (it.value() == sk)
{
//删除项
QList<QListWidgetItem*> list;
list = ui.listWidget_OnlineUser-> findItems(it.key(), Qt::MatchCaseSensitive);
QListWidgetItem* sel = list[0];
int r = ui.listWidget_OnlineUser->row(sel);
QListWidgetItem* item = ui.listWidget_OnlineUser->takeItem(r);
ui.listWidget_OnlineUser->removeItemWidget(item);
delete item;
m_clients.removeOne(sk);
QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
ui.textEdit_RecvMsg->append(time + "" + it.key() + "下线了\n");
temp_key = it.key();
}
}
mapSocket.remove(temp_key);
ui.textEdit_RecvMsg->append("after remove, map size = " + QString(mapSocket.size()) + "\n");
}
}
}
变量和参数定义
#include <QtWidgets/QWidget>
#include "ui_WebsocketServer.h"
#include <QWebSocketServer>
#include <QWebSocket>
#include <QMap>
class WebsocketServerDemo : public QWidget
{
Q_OBJECT
public:
WebsocketServerDemo(QWidget *parent = Q_NULLPTR);
~WebsocketServerDemo();
private slots:
void on_btnOpenServer_clicked();
void on_btnCloseServer_clicked();
void on_btnSend_clicked();
void onNewConnection();
void processTextMessage(QString message);
void socketDisconnected();
private:
Ui::WebsocketServerClass ui;
QWebSocketServer* m_WebSocketServer = nullptr;
QList<QWebSocket*> m_clients;
bool m_debug;
QWebSocket* pSocket;
QDateTime* current_date_time;
QMap<QString, QWebSocket*> mapSocket;
};
QWebSocketClinet的基本使用
对于客户端,只需要指定服务端的 Url。通过 open 函数连接服务端的 Url ,使用 close 关闭连接。数据到来的时候有 textMessageReceived 和 binaryMessageReceived 等信号触发,也可以调用 sendTextMessage 或 sendBinaryMessage 发送数据。
连接服务器并监听连接、断开、消息接收消息的函数。
m_websocket.open(url);
connect(&m_websocket, SIGNAL(connected()), this, SLOT(onconnected()));
connect(&m_websocket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
connect(&m_websocket, SIGNAL(textMessageReceived(QString)), this, SLOT(onTextMessageReceived(QString)));
客户端连接函数处理
//连接上之后
void WebSocketClientDemo::onconnected()
{
ui.label_ConnectStatus->setText(tr("connected"));
ui.btnConnect->setEnabled(false);
ui.btnDisconnect->setEnabled(true);
}
客户端函数处理
主要处理的是界面上的显示
//断开连接操作
void WebSocketClientDemo::closeConnection()
{
ui.label_ConnectStatus->setText("disconnected");
}
消息接收处理
//收到消息
void WebSocketClientDemo::onTextMessageReceived(const QString& message)
{
QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
ui.textEdit_recv->setText(time + "\n" + message);
}
变量和参数定义
#include <QtWidgets/QWidget>
#include "ui_WebSocketClientDemo.h"
#include <QLineEdit>
#include <QLabel>
#include <QTextEdit>
#include <QListWidget>
#include <QPushButton>
#include <QSpinBox>
#include <QButtonGroup>
#include <QObject>
#include <QWidget>
#include <QUrl>
#include <time.h>
#include <QByteArray>
#include <QWebSocket>
class WebSocketClientDemo : public QWidget
{
Q_OBJECT
public:
WebSocketClientDemo(QWidget *parent = Q_NULLPTR);
~WebSocketClientDemo();
private slots:
void on_btnConnect_clicked();
void on_btnDisconnect_clicked();
void on_btnSend_clicked();
void onconnected();
void onTextMessageReceived(const QString& message);
void closeConnection();
private:
Ui::WebSocketClientDemoClass ui;
QUrl m_url;
QWebSocket m_websocket;
bool m_debug;
QDateTime* current_date_time;
};
总结:
1、该示例代码简单实现了webSocketServer的创建。但是并没有用到多线程的技术,所以对并发处理不不适合。文章来源:https://www.toymoban.com/news/detail-656643.html
2、本示例对数据处理,和错误事件并没有很好的解析,这需要后续实现。文章来源地址https://www.toymoban.com/news/detail-656643.html
到了这里,关于QT实现 WebsocketServer端与WebsocketClient 端通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!