【C++】Qt:WebSocket客户端示例

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍WebSocket客户端示例。
学其所用,用其所学。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. WebSocket客户端介绍
    • :blush:2. 环境安装与配置
    • :satisfied:3. 基于Qt的WebSocket客户端示例

😏1. WebSocket客户端介绍

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许在客户端和服务器之间实时交换数据。WebSocket 客户端是指使用 WebSocket 协议与服务器端建立连接并进行数据交换的程序或组件。

实现 WebSocket 客户端的步骤:

  1. 建立连接: WebSocket 客户端首先需要与服务器建立连接,通常通过 WebSocket URL(ws:// 或 wss://)来连接到服务器。

  2. 发送和接收数据: 一旦连接建立成功,客户端可以通过发送消息给服务器来交换数据,并从服务器接收响应消息。

  3. 处理事件: WebSocket 客户端可以监听连接状态、错误和消息等事件,并根据需要处理这些事件。

  4. 关闭连接: 在通信结束后,客户端应该关闭 WebSocket 连接,释放资源。

😊2. 环境安装与配置

Windows + Qt5

效果如下:

在这里插入图片描述

😆3. 基于Qt的WebSocket客户端示例

// qt.pro
QT       += websockets
// websocketclient.h
#ifndef WEBSOCKETCLIENT_H
#define WEBSOCKETCLIENT_H#include <QObject>
#include <QtWebSockets>
#include <QDebug>
#include <QUrl>class WebSocketClient : public QObject
{Q_OBJECT
public:explicit WebSocketClient(QObject *parent = nullptr);~WebSocketClient();void connectUrl(QString url); // 连接websocket服务器的URLvoid close(); // 关闭websocketvoid sendTextMsg(const QString &message); // 发送Text类型的消息void sendBinaryMsg(const QByteArray &data); // 发送Binary类型的消息bool getConStatus(); // 返回服务器连接状态signals:void sigRecvTextMsg(QString message); // 接受到Text类型消息的信号private slots:void slotConnected(); // 连接成功void slotDisconnected(); // 断开连接void slotRecvTextMsg(QString message); // 接受字符数据void slotRecvBinaryMsg(QByteArray message); // 接受二进制数据void slotError(QAbstractSocket::SocketError error); // 响应报错private:void reconnect(); // 断开重连QWebSocket  *m_pWebSocket;QUrl m_url;bool m_bConnected = false; // 为true,表明已连接服务器,否则未连接上
};#endif // WEBSOCKETCLIENT_H// websocketclient.cpp
#include "websocketclient.h"WebSocketClient::WebSocketClient(QObject *parent) : QObject(parent)
{m_pWebSocket = new QWebSocket();// 连接相应的信号槽connect(m_pWebSocket, SIGNAL(connected()), this, SLOT(slotConnected()));connect(m_pWebSocket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));connect(m_pWebSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotError(QAbstractSocket::SocketError)));
}WebSocketClient::~WebSocketClient()
{if(m_pWebSocket != 0){m_pWebSocket->deleteLater();m_pWebSocket = 0;}
}// 连接websocket服务器的URL
void WebSocketClient::connectUrl(QString url)
{m_url = QUrl(url);m_pWebSocket->open(m_url);
}// 关闭websocket
void WebSocketClient::close()
{m_pWebSocket->close();
}// 发送Text类型的消息
void WebSocketClient::sendTextMsg(const QString &message)
{if(!m_bConnected){qDebug() << __FILE__ << __LINE__ << "Failed to" << __FUNCTION__ << ", it's not running...";return;}//qDebug() << "send: " << message;m_pWebSocket->sendTextMessage(message);
}// 发送Binary类型的消息
void WebSocketClient::sendBinaryMsg(const QByteArray &data)
{if(!m_bConnected){qDebug() << __FILE__ << __LINE__ << "Failed to" << __FUNCTION__ << ", it's not running...";return;}m_pWebSocket->sendBinaryMessage(data);
}// 返回服务器连接状态
bool WebSocketClient::getConStatus()
{return m_bConnected;
}// 连接成功
void WebSocketClient::slotConnected()
{qDebug()<<"connect successful";m_bConnected = true;connect(m_pWebSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(slotRecvTextMsg(QString)));connect(m_pWebSocket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(slotRecvBinaryMsg(QByteArray)));
}// 断开连接
void WebSocketClient::slotDisconnected()
{qDebug() << __FILE__ << __LINE__ << "disconnected";reconnect();
}// 接受字符数据
void WebSocketClient::slotRecvTextMsg(QString message)
{emit sigRecvTextMsg(message);
}// 接受二进制数据
void WebSocketClient::slotRecvBinaryMsg(QByteArray message)
{qDebug() << "slotRecvBinaryMsg: " << message;
}// 响应报错
void WebSocketClient::slotError(QAbstractSocket::SocketError error)
{qDebug() << __FILE__ << __LINE__ << (int)error << m_pWebSocket->errorString();
}// 断开重连
void WebSocketClient::reconnect()
{qDebug() << "websocket reconnected";m_pWebSocket->abort();m_pWebSocket->open(m_url);
}
// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QListWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include "websocketclient.h"//namespace Ui {
//class Widget;
//}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private slots:void slotSendMsg(); // 发送消息的槽函数void slotRecvTextMsg(QString sMessage); // 接受WebSocketClient传来的文本消息private:
//    Ui::Widget *ui;QListWidget *listwidget;QLineEdit *lineedit;WebSocketClient *m_pWebSocketClinet; // WebSocket客户端};#endif // WIDGET_H// widget.cpp
#include "widget.h"
//#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent)
//    ui(new Ui::Widget)
{
//    ui->setupUi(this);this->setWindowTitle("WebSocket客户端");// 初始化窗口部件listwidget = new QListWidget;lineedit = new QLineEdit;QPushButton *sendbutton = new QPushButton("发  送");QPushButton *cancelbutton = new QPushButton("取  消");this->connect(sendbutton, SIGNAL(clicked()), this, SLOT(slotSendMsg()));this->connect(cancelbutton, SIGNAL(clicked()), this,SLOT(close()));// 布局QHBoxLayout * hlayout = new QHBoxLayout;hlayout->addStretch(0);hlayout->addWidget(sendbutton);hlayout->addWidget(cancelbutton);QVBoxLayout *vlayout = new QVBoxLayout(this);vlayout->addWidget(listwidget);vlayout->addWidget(lineedit);vlayout->addLayout(hlayout);// 初始化服务器m_pWebSocketClinet = new WebSocketClient;m_pWebSocketClinet->connectUrl("ws://localhost:8080");connect(m_pWebSocketClinet, SIGNAL(sigRecvTextMsg(QString)), this, SLOT(slotRecvTextMsg(QString)));
}Widget::~Widget()
{
//    delete ui;
}// 发送消息的槽函数
void Widget::slotSendMsg()
{QString content = lineedit->text(); //获取单行文本框内要发送的内容if(!content.isEmpty()){QDateTime datetime = QDateTime::currentDateTime();QString str = "send to server : " + datetime.toString("yyyy-M-dd hh:mm:ss") + tr("\n");str += content;listwidget->addItem(str);   // 将要发送的内容显示在listwidgetm_pWebSocketClinet->sendTextMsg(str); // 发送消息到服务器}else{QMessageBox::critical(this, "错误", "不能发送空消息!", QMessageBox::Ok);}lineedit->clear();
}// 接受WebSocketClient传来的文本消息
void Widget::slotRecvTextMsg(QString sMessage)
{// 加上时间帧QDateTime datetime = QDateTime::currentDateTime();QString str = tr("recv from server : ") + datetime.toString("yyyy-M-dd hh:mm:ss") + tr("\n");str += sMessage;listwidget->addItem(str);   // 将接收到的内容加入到listwidget
}

请添加图片描述

以上。

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

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

相关文章

[Halcon学习笔记]实现多边形绘图后自动闭合成斜矩形

1、介绍 在Halcon联合开发项目中&#xff0c;需要在Halcon窗口上绘制不同形状的ROI&#xff0c;但是Halcon自带的绘图操作不太方便&#xff0c;操作时交互感官较差&#xff0c;所以可以通过绘制多边形&#xff0c;通过点来绘制多边形&#xff0c;最后通过闭合算子将绘框形成闭…

大数据技术学习笔记(十三)—— HBase

目录 1 Hbase 概述1.1 Hbase 定义1.2 HBase 数据模型1.2.1 HBase 逻辑结构1.2.2 HBase 物理存储结构1.2.3 数据模型 1.3 HBase 基本架构 2 HBase Shell 操作2.1 基本操作2.2 namespace 操作2.3 表操作 3 HBase 原理深入3.1 RegionServer 架构3.2 HBase 写流程3.3 MemStore Flus…

WPF —— 控件模版和数据模版

1:控件模版简介: 自定义控件模版&#xff1a;自己添加的样式、标签&#xff0c;控件模版也是属于资源的一种&#xff0c; 每一个控件模版都有一唯一的 key&#xff0c;在控件上通过template属性进行绑定 什么场景下使用自定义控件模版&#xff0c;当项目里面多个地方…

Sentinel(流控模式:直接关联链路,流控效果:直接预热排队)

Sentinel能够对流量进行控制&#xff0c;主要是监控应用的QPS流量或者并发线程数等指标&#xff0c;如果达到指定的阈值时&#xff0c;就会被流量进行控制&#xff0c;以避免服务被瞬时的高并发流量击垮&#xff0c;保证服务的高可靠性。 1.流控模式: 直接模式测试案例 表示1…

微信小程序项目实战遇到的问题

我们以学生成绩平台来作为例子。这是我们想得到的效果。 以下是完整代码&#xff1a; index.js // index.js Page({//页面的初始数据data: {hello: 欢迎进入微信小程序的编程世界,score: 80,userArray: [{name: 张三,score: [66, 77, 86, 70, 90]},{name: 李四,score: [88, 7…

如何让自己上百度百科?个人百科词条创建

百度百科&#xff0c;作为我国最大的中文百科全书&#xff0c;其影响力和权威性不言而喻。能够登上百度百科&#xff0c;意味着个人的知名度、成就和社会影响力得到了广泛认可。那么&#xff0c;如何才能让自己上百度百科呢&#xff1f;接下来伯乐网络传媒就来给大家讲解一下。…

MyBatis3源码深度解析(十六)SqlSession的创建与执行(三)Mapper方法的调用过程

文章目录 前言5.9 Mapper方法的调用过程5.10 小结 前言 上一节【MyBatis3源码深度解析(十五)SqlSession的创建与执行(二)Mapper接口和XML配置文件的注册与获取】已经知道&#xff0c;调用SqlSession对象的getMapper(Class)方法&#xff0c;传入指定的Mapper接口对应的Class对象…

C#,图论与图算法,计算无向连通图中长度为n环的算法与源代码

1 无向连通图中长度为n环 给定一个无向连通图和一个数n,计算图中长度为n的环的总数。长度为n的循环仅表示该循环包含n个顶点和n条边。我们必须统计存在的所有这样的环。 为了解决这个问题,可以有效地使用DFS(深度优先搜索)。使用DFS,我们可以找到特定源(或起点)的长度…

十一、MYSQL 基于MHA的高可用集群

目录 一、MHA概述 1、简介 2、MHA 特点 3、MHA 工作原理&#xff08;流程&#xff09; 二、MHA高可用结构部署 1、环境准备 2、安装MHA 监控manager 3、在manager管理机器上配置管理节点&#xff1a; 4、编master_ip_failover脚本写 5、在master上创建mha这个用户来访…

web容器导论

一、基础概念 1.Web容器是什么&#xff1f; 让我们先来简单回顾一下Web技术的发展历史&#xff0c;可以帮助你理解Web容器的由来。 早期的Web应用主要用于浏览新闻等静态页面&#xff0c;HTTP服务器&#xff08;比如Apache、Nginx&#xff09;向浏览器返回静态HTML&#xff…

轻松解锁微博视频:基于Perl的下载解决方案

引言 随着微博成为中国最受欢迎的社交平台之一&#xff0c;其内容已经变得丰富多彩&#xff0c;特别是视频内容吸引了大量用户的关注。然而&#xff0c;尽管用户对微博上的视频内容感兴趣&#xff0c;但却面临着无法直接下载这些视频的难题。本文旨在介绍一个基于Perl的解决方…

PHP/后端/Tp/fastadmin/消息通知企业微信机器人

第一步&#xff0c;先在企业微信的群聊里面添加一个机器人。 第二步&#xff0c;复制获取机器人的WebHook地址 第三步&#xff0c;拼接发送内容 public function webhook(){//机器人webhook地址 $url https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyca8c9c-72b1-4faf-…

基于python+vue智慧社区家政服务系统的设计与实现flask-django-nodejs

论文主要是对智慧社区家政服务系统进行了介绍&#xff0c;包括研究的现状&#xff0c;还有涉及的开发背景&#xff0c;然后还对系统的设计目标进行了论述&#xff0c;还有系统的需求&#xff0c;以及整个的设计方案&#xff0c;对系统的设计以及实现&#xff0c;也都论述的比较…

基于docker+rancher部署Vue项目的教程

基于dockerrancher部署Vue的教程 前段时间总有前端开发问我Vue如何通过docker生成镜像&#xff0c;并用rancher上进行部署&#xff1f;今天抽了2个小时研究了一下&#xff0c;给大家记录一下这个过程。该部署教程适用于Vue、Vue2、Vue3等版本。 PS&#xff1a;该教程基于有一定…

Android 项目实战,APP开发,含源码

Android 项目实战&#xff0c;APP开发&#xff0c;含源码 源码项目详情 源码项目详情 切鱼达人&#xff0c;Android休闲游戏开发 打砖块&#xff0c;Android休闲小游戏开发 “牛弹琴”&#xff0c;Android 弹钢琴 app 开发 2048 数字合成大作战&#xff0c;Android小游戏开…

Flink中JobManager与TaskManage的运行架构以及原理详解

Flink中JobManager与TaskManage的运行架构详解 整体架构 Flink的运行时架构中&#xff0c;最重要的就是两大组件&#xff1a;作业管理器&#xff08;JobManger&#xff09;和任务管理器&#xff08;TaskManager&#xff09;。对于一个提交执行的作业&#xff0c;JobManager是真…

lang-segment-anything使用介绍

Language Segment-Anything 是一个开源项目&#xff0c;它结合了实例分割和文本提示的强大功能&#xff0c;为图像中的特定对象生成蒙版。它建立在最近发布的 Meta 模型、segment-anything 和 GroundingDINO 检测模型之上&#xff0c;是一款易于使用且有效的对象检测和图像分割…

软件工程-第8章 软件测试

8.1 软件测试目标域软件测试过程模型 8.2 软件测试技术 8.3 静态分析技术-程序正确性证明 8.4 软件测试步骤 8.5 本章小结

基于支持向量机(SVM)的数据时序预测(单输入输出)

代码原理 支持向量机(SVM)通常被用于处理分类问题,而对于数据时序预测(单输入输出),可以采用以下步骤使用SVM进行建模: 1. 数据准备:准备时间序列数据集,包括历史观测值和对应的目标值,按照时间顺序排列。 2. 特征提取:将时间序列数据转换为模型可接受的特征表示…

卷积神经网络五:GoogleNet

在2014年的ImageNet图像识别大赛中&#xff0c;一个名叫GoogleNet的网络架构大放异彩。GoogleNet使用了一种叫作Inception的结构。其实GoogleNet本质上就是一种Inception网络&#xff0c;而一个Inception网络又是由多个Inception模块和少量的汇聚层堆叠而成。 Inception模块 …