【QT】Qt中Websocket的使用

一、WebSocket的定义

        WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。        

        WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。想对应http协议来说,websocket更加的平等,在http协议中,只有客户端向服务器发送申请请求之后,服务器才会返回请求的数据,如果要保证实时性的话,就需要不断地轮询,每隔一段时间就向服务器发送一个请求,这样就会造成很大的开销,而WebSocket服务器主动向客户端发送数据,而不需要申请,客户端发送数据给服务器也是如此

        简单来说,就是浏览器和服务器之间通信的一种协议,相比较http来说,数据交换更加平等,开销更小;

二、服务器和客户端

        要想在Qt实现websocket那么我们主要的就是实现一个服务器,由网页实现一个客户端

2.1 服务器的实现

        要实现服务器,首先要认识QWebSocketServer Class,我们需要通过这个类实现

 1)类分析

        从上图可以知道,需要在.pro文件中添加QT+=websockets,然后添加头文件,新建一个WebSocketTest窗口应用程序,试图如下

2)添加库

        在WebSocketTest中添加下面的语句

QT       += websockets

3)添加头文件

        在websockettest.h中添加头文件,声明变量

#ifndef WEBSOCKETTEST_H
#define WEBSOCKETTEST_H#include <QWidget>
#include <QWebSocketServer>QT_BEGIN_NAMESPACE
namespace Ui { class WebSocketTest; }
QT_END_NAMESPACEclass WebSocketTest : public QWidget
{Q_OBJECTpublic:WebSocketTest(QWidget *parent = nullptr);~WebSocketTest();private:Ui::WebSocketTest *ui;//声明QWebSocketServer变量QWebSocketServer *web_server;};
#endif // WEBSOCKETTEST_H

4)QWebSocketServer类的使用

        再来看一看关于这个类的使用,类名上面F1进入帮助界面,可以看到

翻译过来就是

QWebSocketServer是一个基于QTcpServer模型的类,用于处理WebSocket协议的服务器端通信。如果你知道如何使用QTcpServer,你就可以很轻松的使用QWebSocketServer。

QWebSocketServer类主要用于接收并处理来自客户端的WebSocket连接,你可以手动设定服务端的端口,也可以让QWebSocketServer自动选择。调用listen()函数即可让服务器开始侦听连接请求。

每当有新的客户端尝试连接服务器时,newConnection()信号就会发出。服务器可以调用nextPendingConnection()方法接受这个握手请求,同时返回一个已经连接状态的QWebSocket对象指针,服务器即可通过这个指针和客户端进行通信。

如果在过程中发生错误,serverError()方法可以获取错误类型,同时可以调用errorString()方法获取人类可读的错误描述。

当服务器侦听连接请求时,可以通过serverAddress()和serverPort()来获取服务器正在侦听的地址和端口。调用close()函数可以使QWebSocketServer停止侦听连接请求。

QWebSocketServer当前还不支持WebSocket拓展和WebSocket子协议。该类仅支持RFC 6455中规定的WebSocket协议的13版。

有一个默认的握手超时设置为10秒,主要用于防止拒绝服务攻击,该超时时间可以通过setHandshakeTimeout()自定义。

参见WebSocket Server Example和QWebSocket。

        也就是说使用listen函数监听连接请求,一旦有新的客户端连接,就可以触发newConnection()信号,再由服务器通过nextPendingConnection()方法接收这个客户端的连接,这个方法返回一个QWebsocket的对象指针,通过这个指针就可以和客户端通信了

5)代码实现

        首先客户端代码我这里直接提供一个可以测试的html,新建一个文本文件,将下面内容复制进去,保存后,将后缀改为html,点击使用浏览器打开。

<!DOCTYPE html>
<html>
<head>
<title>WebSocket Test</title>
<style>#testButton {display: block;margin: 20px auto;padding: 10px 20px;font-size: 16px;}#messageDisplay {margin: 20px auto;padding: 10px;border: 1px solid #ccc;width: 80%;height: 200px;overflow-y: scroll;font-size: 14px;}
</style>
</head>
<body>
<button id="testButton">Send Test Message</button>
<div id="messageDisplay"></div><script>
var ws = new WebSocket('ws://localhost:15678');ws.onopen = function() {console.log('WebSocket connection opened.');
};ws.onmessage = function(event) {console.log('Message from server:', event.data);var messageDisplay = document.getElementById('messageDisplay');messageDisplay.innerHTML += '<p>' + event.data + '</p>';
};ws.onerror = function(error) {console.error('WebSocket error:', error);
};ws.onclose = function() {console.log('WebSocket connection closed.');
};document.getElementById('testButton').onclick = function() {ws.send('Test');console.log('Test message sent.');
};
</script>
</body>
</html>

服务器相关代码

构造函数

 web_server = new QWebSocketServer("Myserver",QWebSocketServer::NonSecureMode,this);if(web_server->listen(QHostAddress::Any,15678)){qDebug()<<"开始监听";connect(web_server,&QWebSocketServer::newConnection,this,&WebSocketTest::newCilentConnect);}

槽函数

void WebSocketTest::newCilentConnect()
{//返回客户端web_client = web_server->nextPendingConnection();qDebug() << "有新的 WebSocket 客户端连接。";}

编译运行服务器,然后点击html文件,可以发现会打印”有新的 WebSocket 客户端连接“;

6)接收客户端的消息

void WebSocketTest::newCilentConnect()
{//返回客户端web_client = web_server->nextPendingConnection();qDebug() << "有新的 WebSocket 客户端连接。";// 处理接收到的消息connect(web_client , &QWebSocket::textMessageReceived, this, &WebSocketTest::onTextMessageReceived);}void WebSocketTest::onTextMessageReceived(const QString &message)
{qDebug() << "收到客户端消息:" << message;if(message=="Test"){/*在这里执行你实现的操作,如网页一个按钮,点击后发送打开摄像头信息给服务器,服务器执行打开摄像头的操作*/}
}

        编译运行,点击网页上的按钮,服务器就可以收到这个消息了;

2.2 客户端的实现

        到前面为止就可以实现客户端发送数据到服务器的操作,现在实现服务器发送数据给客户端


// 向客户端发送数据
void WebSocketTest::sendClientData(const QString &str)
{if (web_client->isValid()) {web_client->sendTextMessage(str);}
}

然后在界面上添加一个按钮发送信息给客户端


void WebSocketTest::on_btn_send_clicked()
{sendClientData("Hello");
}

编译运行,刷新网页后,点击按钮查看效果

 三、完整源码

websocket.c

#include "websockettest.h"
#include "ui_websockettest.h"WebSocketTest::WebSocketTest(QWidget *parent): QWidget(parent), ui(new Ui::WebSocketTest)
{ui->setupUi(this);// 创建 WebSocket 服务器web_server = new QWebSocketServer("Myserver",QWebSocketServer::NonSecureMode,this);//监听if(web_server->listen(QHostAddress::Any,15678)){qDebug()<<"开始监听";connect(web_server,&QWebSocketServer::newConnection,this,&WebSocketTest::newCilentConnect);}}void WebSocketTest::newCilentConnect()
{web_client = web_server->nextPendingConnection();qDebug() << "有新的 WebSocket 客户端连接。";// 处理客户端断开连接connect(web_client, &QWebSocket::disconnected, this, [this, web_client]() {qDebug() << "WebSocket 客户端断开连接。";web_client->deleteLater();});// 处理接收到的消息connect(web_client, &QWebSocket::textMessageReceived, this, &WebSocketTest::onTextMessageReceived);}
void WebSocketTest::onTextMessageReceived(const QString &message)
{qDebug() << "收到客户端消息:" << message;}// 向客户端发送数据
void WebSocketTest::sendClientData(const QString &str)
{if (web_client->isValid()) {web_client->sendTextMessage(str);}
}void WebSocketTest::on_btn_send_clicked()
{sendClientData("Hello");
}WebSocketTest::~WebSocketTest()
{delete ui;
}

websocket.h

#ifndef WEBSOCKETTEST_H
#define WEBSOCKETTEST_H#include <QWidget>
#include <QWebSocketServer>
#include <QDebug>
#include <QWebSocket>QT_BEGIN_NAMESPACE
namespace Ui { class WebSocketTest; }
QT_END_NAMESPACEclass WebSocketTest : public QWidget
{Q_OBJECTpublic:WebSocketTest(QWidget *parent = nullptr);~WebSocketTest();private:Ui::WebSocketTest *ui;//声明QWebSocketServer变量  服务器QWebSocketServer *web_server;//客户端QWebSocket* web_client;private slots://客户端连接槽函数void newCilentConnect();//接收新客户端消息函数void onTextMessageReceived(const QString &message);//发送消息给客户端函数void on_btn_send_clicked();private://发送消息给客户端void sendClientData(const QString &str);};
#endif // WEBSOCKETTEST_H

websocket.html

<!DOCTYPE html>
<html>
<head>
<title>WebSocket Test</title>
<style>#testButton {display: block;margin: 20px auto;padding: 10px 20px;font-size: 16px;}#messageDisplay {margin: 20px auto;padding: 10px;border: 1px solid #ccc;width: 80%;height: 200px;overflow-y: scroll;font-size: 14px;}
</style>
</head>
<body>
<button id="testButton">Send Test Message</button>
<div id="messageDisplay"></div><script>
var ws = new WebSocket('ws://localhost:15678');ws.onopen = function() {console.log('WebSocket connection opened.');
};ws.onmessage = function(event) {console.log('Message from server:', event.data);var messageDisplay = document.getElementById('messageDisplay');messageDisplay.innerHTML += '<p>' + event.data + '</p>';
};ws.onerror = function(error) {console.error('WebSocket error:', error);
};ws.onclose = function() {console.log('WebSocket connection closed.');
};document.getElementById('testButton').onclick = function() {ws.send('Test');console.log('Test message sent.');
};
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394517.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arcgis(shp)注记转CAD(dwg)文字

arcgis&#xff08;shp&#xff09;注记转CAD&#xff08;dwg&#xff09;文字方法如下&#xff1a; 1、添加shp文件&#xff0c;标注要素&#xff0c;然后选标注转注记 2、 点击文件夹图标打开文件夹&#xff0c;选择保存路径。&#xff08;提前需新建好文件地理数据库、数据…

#java学习笔记(面向对象)----(未完结)

一基础相关知识点&#xff1a; 1. 一个对象的调用 首先我们创建一个Phone类 public class Phone {//成员变量String name;int age;String favourite;//成员方法public void myName(){System.out.println(name);}public void myAge(){System.out.println(age);}public void m…

Flink实时数仓(六)【DWD 层搭建(四)交易域、互动域、用户域实现】

前言 今天的任务是完成 DWD 层剩余的事实表&#xff1b;今年的秋招开得比往年早&#xff0c;所以要抓紧时间了&#xff0c;据了解&#xff0c;今年的 hc 还是不多&#xff0c;要是晚点投铁定寄中寄了&#xff1b; 今天还是个周末&#xff0c;不过记忆里我好像整个大学都没有好好…

山姆.奥特尔曼发文暗示:新模型“草莓“即将发布?

山姆.奥特尔曼发文 山姆.奥特尔曼在今天发布了一条推特,图片中所展示的是已经成熟的几颗草莓。要知道之前的"草莓"事件闹的可是沸沸扬扬,而恰巧山姆.奥特尔曼在此时又发出了一条这样的文章。会不会是刻意的在暗示什么呢? 新的模型即将发布&#xff1f; 山姆.奥特尔曼…

视频编辑SDK解决方案,提升了视频内容的趣味性和观赏性

美摄科技&#xff0c;作为视频编辑技术的领航者&#xff0c;凭借其前沿的视频编辑SDK解决方案&#xff0c;正以前所未有的方式&#xff0c;重新定义着互联网泛娱乐、硬件大屏、匿名社交等多个行业场景的体验边界。我们不仅仅是在编辑视频&#xff0c;更是在编织一个充满想象与互…

GIt最新教程通俗易懂

Git学习笔记 一、Git版本控制分类1.1 本地版本控制1.2 集中版本1.3 分布式版本控制系统1.5 Git和SVN的区别二、Git的历史 三、Gti基础学习3.1 Git的基础学习3.2 启动Git 3.3 Git基本的配置3.3.1 配置文件相关位置 四、Git基本理论&#xff08;核心&#xff09;4.1 Git 的工作流…

自驾畅游保定:参观总督署,品美食文化

这是学习笔记的第 2490篇文章 前几天跟孩子聊天&#xff0c;孩子说暑假都没出去玩了&#xff0c;暑假旅行的作业咋写&#xff1f;让我有满满的负疚感&#xff0c;去附近的公园、吃点美食不算旅游&#xff0c;得了&#xff0c;得安排一下一日游。 几个月前心心念的去保定&#x…

Vue 3+Vite+Eectron从入门到实战系列之(四)一Electron热身运动(二)

在electron里面能不呢实现暗黑模式和明亮模式的切换&#xff1f;我们怎么读取主进程里面的数据和系统数据。这篇就是来实现这几个效果的 实现效果 更改系统的主题色 在 App.vue 中添加代码。 <el-button type"warning" click"changeTheme">更改系…

红豆0感舒适衬衫2.0,让这个七夕节变得有点不一样

七夕节又到了&#xff0c;在这个佳人相约的传统节日&#xff0c;红豆舒适男装以“七夕穿红豆 爱人更舒适”为主题带来了24届红豆七夕节。 这是红豆集团连续24年举办红豆七夕节&#xff0c;红豆七夕节也不仅是广受年轻人喜爱的传统节日盛典&#xff0c;同样也是红豆集团打造的特…

CV党福音:YOLOv8实现分类

YOLO作为目标检测领域的常青树&#xff0c;如今以及更新到了YOLOv10&#xff0c;并且还有YOLOX、YOLOS等变体&#xff0c;可以说该系列已经在目标检测领域占据了半壁江山&#xff0c;如今&#xff0c;YOLOv8的发行者ultralytics竟有一统江山之意&#xff0c;其在提出的框架中不…

【书生大模型实战营(暑假场)】入门任务二 Git 关卡

入门任务二 Git 关卡 参考&#xff1a; 教程任务 注意&#xff1a; 项目Github链接 1 闯关任务 1.1 使用 Git 完成破冰介绍 本任务将基于开发机实现&#xff0c;重点在于熟悉Git操作。首先要了解 Git操作的常见四部曲&#xff0c;即&#xff1a;舔 Add&#xff0c;提 Co…

计算机毕业设计选题推荐-电缆行业生产管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

Gradle 入门指南:从安装到基础用法详解

文章目录 Gradle 简介安装 Gradle创建和配置 Gradle 项目将 Gradle 项目打成jar包多项目聚合示例项目结构步骤详解 Gradle 简介 Gradle 是一个基于 Groovy 和 Kotlin 的构建工具&#xff0c;用于自动化构建、依赖管理和项目管理。它结合了 Maven 的依赖管理和 Ant 的灵活性&am…

【MySQL】库操作,数据类型

目录 MySQL简介SQL语句分类库操作语句展示数据库创建数据库使用数据库删除数据库 数据类型整型浮点型字符串日期类型 MySQL简介 数据库有关系型数据库和非关系型数据库。 关系型数据库&#xff1a;是指采用了关系模型来组织数据的数据库。 简单来说&#xff0c;关系模型指的就…

智能化的Facebook未来:AI如何重塑社交网络的面貌?

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;社交网络的面貌正在经历深刻的变革。Facebook&#xff08;现Meta Platforms&#xff09;作为全球最大的社交媒体平台之一&#xff0c;正积极探索如何利用AI技术来提升用户体验、优化内容管理并推动平台创新。…

线上预约陪诊平台医院陪诊系统源码就医陪护小程序APP开发

项目分析 随着医疗行业的数字化转型和人们对健康需求的日益增长&#xff0c;线上预约陪诊系统作为一种新兴的医疗服务模式&#xff0c;正逐渐受到市场的关注和认可。本文将从市场前景、使用人群、盈利模式以及竞品分析等多个角度&#xff0c;全面探讨线上预约陪诊系统的技术性…

【稳定ACM出版、EI检索|武汉场线上线下结合】2024年第五届医学人工智能国际学术会议(ISAIMS 2024,8月13-17)

第五届医学人工智能国际学术会议&#xff08;ISAIMS2024&#xff09;将于2024年8月13-17日于荷兰阿姆斯特丹自由大学召开&#xff0c;国内分会场将于2024年10月25-27日于中国武汉召开。 本届会议将继续围绕人工智能在医学领域的最新研究成果&#xff0c;为来自国内外高等院校、…

反转链表(LeetCode)

题目 给你单链表的头节点&#xff0c;请你反转链表&#xff0c;并返回反转后的链表 解题 class ListNode:def __init__(self, value0, nextNone):self.value valueself.next nextdef reverse_linked_list_recursive(head: ListNode) -> ListNode:# 空链表或单节点链表if …

计算机网络-传输层

网络层不具有重传&#xff0c;需要传输层来控制。 Tcp&#xff1a;需要将传输的数据进行分段传输&#xff0c;并且能够建立会话&#xff0c;具备流量控制&#xff0c;是一种可靠的传输协议UDP&#xff1a;一个数据包就能完成数据通信&#xff0c;不分段&#xff0c;不需要建立…

人工智能|人工智能教育的发展现状及趋势

智能的热潮正席卷全球。国家在人工智能领域展开战略布局&#xff0c;人工智能人才成为国家急需的高层次技术人才。据领英发布的《全球 Al 领域人才报告》显示&#xff0c;国内人工智能人才缺口达到 500 多万。 毫无疑问&#xff0c;人工智能将不可阻挡地影响所有产业。给自己一…