QT实现 WebsocketServer端与WebsocketClient 端通信

news/2024/4/19 0:06:02

概 述

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保存到mapmapSocket[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_OBJECTpublic: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_OBJECTpublic: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的创建。但是并没有用到多线程的技术,所以对并发处理不不适合。

2、本示例对数据处理,和错误事件并没有很好的解析,这需要后续实现。


https://dhexx.cn/news/show-4626908.html

相关文章

《Apollo 智能驾驶进阶课程》

来自 &#xff1a; https://www.bilibili.com/video/BV1G341117NQ/ https://apollo.baidu.com/ 主要学习资源如下&#xff1a; Apollo社区公众号&#xff0c;直接有整个视频教程的微信推文教程&#xff1a;链接一个CSDN博主记录的笔记&#xff1a; https://blog.csdn.net/qq_45…

Python遍历网格中每个点

遍历网格中每个点 1. 问题描述2. Python实现2.1 网格参数初始化2.2 遍历赋值2.3 矩阵赋值1. 问题描述 最近需要实现一个对矩阵赋值并对矩阵表示的网格参数进行测试的任务,写了一段代码提供参考。 假设网格的长宽均为 2. Python实现 2.1 网格参数初始化 首先定义好需要划分…

【AI】Stable-Diffusion-WebUI使用指南

注&#xff1a;csdn对图片有审核&#xff0c;审核还很奇葩&#xff0c;线稿都能违规&#xff0c;为保证完整的阅读体验建议移步至个人博客阅读 最近AI绘画实现了真人照片级绘画水准&#xff0c;导致AI绘画大火&#xff0c;公司也让我研究研究&#xff0c;借此机会正好了解一下…

深度学习应用篇-计算机视觉-图像增广[1]:数据增广、图像混叠、图像剪裁类变化类等详解

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

Eclipse 教程 完结

Eclipse 快捷键 关于快捷键 Eclipse 的很多操作都提供了快捷键功能&#xff0c;我们可以通过键盘就能很好的控制 Eclipse 各个功能&#xff1a; 使用快捷键关联菜单或菜单项使用快捷键关联对话窗口或视图或编辑器使用快捷键关联工具条上的功能按钮 Eclipse 快捷键列表可通过…

华为OD机试真题 Java 实现【找终点】【2023 B卷 100分】,附详细解题思路

一、题目描述 给定一个正整数数组&#xff0c;设为nums&#xff0c;最大为100个成员&#xff0c;求从第一个成员开始&#xff0c;正好走到数组最后一个成员&#xff0c;所使用的最少步骤数。 要求&#xff1a; 第一步必须从第一元素开始&#xff0c;且1 < 第一步的步长 &…

冈萨雷斯DIP第6章知识点

6.1 彩色基础 区分不同颜色的特性&#xff1f; 区分不同颜色的特性通常是亮度、色调和饱和度。 亮度&#xff1a;亮度体现的是发光强度的消色概念&#xff08;不包含颜色的概念&#xff09;色调&#xff1a;表示被观察者感知的主导色&#xff0c;通常是混合光波中与主波长相关的…

基于机器学习的内容推荐算法及其心理学、社会学影响闲谈

基于机器学习的内容推荐算法目前在各类内容类APP中使用的非常普遍。在购物、时尚、新闻咨询、学习等领域&#xff0c;根据用户的喜好&#xff0c;进行较为精准的用户画像与内容推荐。此类算法不但可以较为准确的分析用户的特征&#xff0c;如年龄、性别等&#xff0c;还能通过长…

钉钉小程序页面之间传递数据如何传递对象

今天写代码的时候&#xff0c;发现了一个问题&#xff0c;在钉钉小程序页面之间传递对象数据的时候&#xff0c;如果直接传递一个对象那个的话&#xff0c;接收的那个页面得到的是一个【object Object】&#xff0c;而并非里面的数据&#xff0c;所以针对上述问题&#xff0c;下…

MMPose关键点检测实战

安装教程 https://github.com/TommyZihao/MMPose_Tutorials/blob/main/2023/0524/%E3%80%90A1%E3%80%91%E5%AE%89%E8%A3%85MMPose.ipynb git clone https://github.com/open-mmlab/mmpose.git -b tutorial2023 -b代表切换到某个分支&#xff0c;保证分支和作者的教程一致 ra…