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

news2024/11/29 10:39:24

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍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服务器的URL
    void close(); // 关闭websocket
    void 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_OBJECT

public:
    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);   // 将要发送的内容显示在listwidget
        m_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.coloradmin.cn/o/1529846.html

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

相关文章

Python分析无人驾驶汽车在桂林市文旅行业推广的问卷

【项目背景】 通过市场调研、文本分析、访谈和问卷调查等方法&#xff0c;探讨&#xff1a; 网民对无人驾驶汽车出行服务的态度。无人驾驶安全员的行业背景。不同人群在旅游时的交通选择偏好。游客及当地居民对桂林市文旅路线的交通满意度。乘客对无人驾驶汽车的满意度。桂林…

X1 grok-1 开源大语言模型下载

Grok 前言 我们正在发布我们的大型语言模型 Grok-1 的基本模型权重和网络架构。Grok-1 是一个 3140 亿参数的专家混合模型&#xff0c;由 xAI 从头开始训练。 这是 2023 年 10 月结束的 Grok-1 预训练阶段的原始基础模型检查点。这意味着该模型不会针对任何特定应用&#xff…

C++特性三:多态的基本语法及原理剖析

一、多态的基本语法 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名 动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数地址早绑定 - 编译阶段确定函数地址 动态多态的函数地址晚绑定 - 运…

GitHub Copilot+ESP开发实战-串口

上篇文章讲了GitHub Copilot在应用中可能遇到的问题&#xff0c;接下来小启就简单介绍下GitHub Copilot在ESP32开发中C语言实现串口功能&#xff0c;感兴趣的可以看看。 一、向Copilot提问&#xff1a; 1. ESP32用C语言实现串口初始化&#xff1b; 2.配置uart为1&#xff0c…

wayland(xdg_wm_base) + egl + opengles 使用 Assimp 加载带光照信息的材质文件Mtl 实现光照贴图的最简实例(十七)

文章目录 前言一、3d 立方体 model 属性相关文件1. cube1.obj2. cube1.Mtl3. 纹理图片 cordeBouee4.jpg二、实现光照贴图的效果1. 依赖库和头文件1.1 assimp1.2 stb_image.h2. egl_wayland_obj_cube1.cpp3. Matrix.h 和 Matrix.cpp4. xdg-shell-client-protocol.h 和 xdg-shell…

9.登入页面

登入页面 在pages中新建页面login 修改代码 <template><view></view> </template><script setup></script><style lang"scss"></style>添加头像组件 官网 https://vkuviewdoc.fsq.pub/components/avatar.html …

原生html vue3使用element plus 的树tree上移下移案例源码

上效果 html源码 <!DOCTYPE html> <html lang"en"> <!-- * Name: mallSalesReports.html * Description: * Author Lani * date 2024-02-28 18:32:36 --> <head><meta charset"UTF-8"><meta name"viewport" …

mapstruct学习笔记-pojo之间的转换

1、前言 mapstruct中常用注解如Mapping,AfterMapping,BeanMapping等的使用,通过案例说明各式各样的业务pojo对象之间如何借助mapstruct完成相互之间的转换,减少代码量的同时也能突出业务逻辑流程,让你的代码里写起来更有规范可言。 2、简介 Reference Guide – MapStruct 3…

【GPT概念01】生成式预训练转换器

一、说明 本文对GPT有所描述&#xff0c;主要解释了GPT的重要环节&#xff1a;only解码器。以及这个过程中&#xff0c;原始数据的维度演进、变化过程。对于想知道GPT内结构的朋友能有一定帮助。 二、唯一解码器模型入门 — 因果语言建模 Decoder only Model&#xff1a;唯一解…

Go web 基础相关知识

Go web Web工作方式 浏览器本身是一个客户端&#xff0c;当你输入URL的时候&#xff0c;首先浏览器会去请求DNS服务器&#xff0c;通过DNS获取相应的域名对应的IP&#xff0c;然后通过IP地址找到IP对应的服务器后&#xff0c;要求建立TCP连接&#xff0c;等浏览器发送完HTTP …

QT配置libtorch(一步到位!!!防止踩坑)

QT配置libtorch Qt下载QT配置MSVCQT配置Libtorch Qt下载 Qt点击下载 Qt的安装选择MSVC2017 64-bit(一定要安装&#xff0c;这关乎后面的配置&#xff01;&#xff01;&#xff01;)&#xff0c;其他的根据自己的选择进行安装 QT配置MSVC Visual Studio点击安装 这里需要安装VS以…

PwnLab靶场PHP伪协议OSCP推荐代码审计命令劫持命令注入

下载链接&#xff1a;PwnLab: init ~ VulnHub 安装&#xff1a; 打开vxbox直接选择导入虚拟电脑即可 正文&#xff1a; 先用nmap扫描靶机ip nmap -sn 192.168.1.1/24 获取到靶机ip后&#xff0c;对靶机的端口进行扫描&#xff0c;并把结果输出到PwnLab文件夹下&#xff0c;命名…

Spark相关

1.Hadoop主要有哪些缺点&#xff1f;相比之下&#xff0c;Spark具有哪些优点&#xff1f; Hadoop主要有哪些缺点&#xff1a;Hadoop虽然已成为大数据技术的事实标准&#xff0c;但其本身还存在诸多缺陷&#xff0c;最主要的缺陷是 MapReduce计算模型延迟过高&#xff0c;无法胜…

Swift中 any some的作用

前言 在学习Swift ui看到一个函数返回了some view。view我可以理解那some是什么&#xff1f; //ContentView.swift struct ContentView_Previews: PreviewProvider{static var previews: some View{ContentView()} }如果你仔细看一些官方文档甚至还有any关键字&#xff0c;也…

GPT实战系列-智谱GLM-4的模型调用

GPT实战系列-智谱GLM-4的模型调用 GPT专栏文章&#xff1a; GPT实战系列-实战Qwen通义千问在Cuda 1224G部署方案_通义千问 ptuning-CSDN博客 GPT实战系列-ChatGLM3本地部署CUDA111080Ti显卡24G实战方案 GPT实战系列-Baichuan2本地化部署实战方案 GPT实战系列-让CodeGeeX2帮…

日本技术,马来西亚制造:NBR SELE COT无硫手指套的革命性性能

在现代工业领域&#xff0c;对于保持生产环境的洁净和高效至关重要。而一种名为NBR SELE COT的无硫手指套正是满足这一需求的理想选择。这款手指套由日本技术开发&#xff0c;采用马来西亚原材料制造&#xff0c;凭借其卓越的性能在工业行业中广受好评。 NBR SELE COT手指套具有…

云平台一键迁移(腾讯云windos服务器迁移到阿里云windos服务器)

参考文档 https://help.aliyun.com/zh/smc/use-cases/one-click-cloud-platform-migration 迁移文档 https://cloud.tencent.com/document/product/598/37140 #腾讯密钥创建 https://cloud.tencent.com/document/product/1340/51945 安装腾讯云自动化服务助手 一.导入迁移…

web前端框架设计第二课-Vue.js简介

web前端框架设计第二课-Vue.js简介 一.预习笔记 1.Vue.js概述 Vue.js是一套用于构建用户界面的渐进式框架。本质上是一个用于开发Web前端界面的库&#xff0c;其本身具有响应式编程和组件化的特点。 Vue.js的特性&#xff1a; 轻量级 数据绑定 应用指令 插件化开发 2.V…

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

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

云原生:重塑未来应用的基石

随着数字化时代的不断深入&#xff0c;云原生已经成为了IT领域的热门话题。它代表着一种全新的软件开发和部署范式&#xff0c;旨在充分利用云计算的优势&#xff0c;并为企业带来更大的灵活性、可靠性和效率。今天我们就来聊一聊这个热门的话题&#xff1a;云原生~ &#x1f4…