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

😏*★,°* :.☆( ̄▽ ̄)/$:.°★ 😏

这篇文章主要介绍WebSocket客户端示例。
学其所用,用其所学。------梁启超

欢迎来到我的博客,一起学习,共同进步。

喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • [:smirk:1. WebSocket客户端介绍](#:smirk:1. WebSocket客户端介绍)
    • [:blush:2. 环境安装与配置](#:blush:2. 环境安装与配置)
    • [:satisfied:3. 基于Qt的WebSocket客户端示例](#: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客户端示例

cpp 复制代码
// 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);
}
cpp 复制代码
// 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
}

以上。

相关推荐
小poop5 小时前
string 类从入门到深入
c++
眠りたいです6 小时前
现代C++:C++14中的新语言特性和库特性
c语言·开发语言·c++
浅念-7 小时前
LeetCode 回溯算法题——综合练习
数据结构·c++·算法·leetcode·职场和发展·深度优先·dfs
楼田莉子8 小时前
C++17新特性:__had_include/属性/求值顺序规则
开发语言·c++·后端
h_a_o777oah9 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
maineKit10 小时前
VS Code 搭建 Qt 6 开发环境保姆级教程:CMake / qmake、MSVC / MinGW 四种组合全覆盖
qt
雪度娃娃11 小时前
Asio异步读写——连接的安全回收问题
开发语言·c++·安全·php
不吃土豆的马铃薯11 小时前
Spdlog 进阶:日志基本控制、日志格式控制、异步记录器
linux·服务器·开发语言·前端·c++
ai安歌11 小时前
鸿蒙PC:Qt适配OpenHarmony实战【取色间】:RGB 滑动调整、HEX 展示和颜色预览
qt·华为·harmonyos
liulilittle12 小时前
TCP UCP:基于卡尔曼滤波的BBR增强型拥塞控制算法
linux·网络·c++·tcp/ip·算法·c·通讯