当前位置: 代码网 > it编程>编程语言>C/C++ > 【QT开发】WebSocket通信QWebSocket类详解及实战应用

【QT开发】WebSocket通信QWebSocket类详解及实战应用

2024年08月03日 C/C++ 我要评论
QWebSocket是Qt提供的一个功能强大且灵活的WebSocket通信类,通过本篇文章的学习,你应该对QWebSocket有了全面的理解,能够在自己的项目中正确使用它。QWebSocket在用户界面中帮助你实现实时数据传输和消息推送,实现交互式和响应式的实时通信,有助于创建用户友好和高效的实时通信应用场景。

qwebsocket是qt提供的一个功能强大且灵活的websocket通信类,通过本篇文章的学习,你应该对qwebsocket有了全面的理解,能够在自己的项目中正确使用它。qwebsocket在用户界面中帮助你实现实时数据传输和消息推送,实现交互式和响应式的实时通信,有助于创建用户友好和高效的实时通信应用场景。


在这里插入图片描述
在这里插入图片描述

🌟概述

qwebsocket是qt网络模块中的一个类,用于实现websocket协议的通信。websocket是一种全双工的通信协议,允许在客户端和服务器之间建立实时的双向通信。qwebsocket提供了对websocket协议的支持,使得开发者能够在qt应用中方便地实现实时通信功能。

qwebsocket在需要实时数据传输、消息推送等场景中非常常见,如聊天室、实时数据流、在线游戏等。

📖 qwebsocket类介绍

在qt官方文档中,qwebsocket类的定义如下:

class qwebsocket : public qiodevice
{
    q_object
    // ...
}

qwebsocket继承自qiodevice,是一个用于实现websocket通信的类。以下是一些关键特性和功能:

  • 全双工通信:支持客户端和服务器之间的双向实时通信。
  • 文本和二进制数据传输:支持传输文本和二进制数据。
  • ssl/tls加密:支持ssl/tls加密通信,确保数据传输的安全性。
  • 连接管理:提供连接管理功能,包括连接、断开连接、重连等。

常用方法

以下是qwebsocket类中一些常用的方法及其简要介绍:

  • 构造函数和析构函数:

    • qwebsocket(const qstring &origin = qstring(), qwebsocketprotocol::version version = qwebsocketprotocol::versionlatest, qobject *parent = nullptr):构造函数,创建一个qwebsocket对象。
    • ~qwebsocket():析构函数,销毁qwebsocket对象。
  • 连接和断开连接:

    • void open(const qurl &url):连接到指定的websocket服务器。
    • void close(qwebsocketprotocol::closecode closecode = qwebsocketprotocol::closecodenormal, const qstring &reason = qstring()):关闭websocket连接。
  • 数据传输:

    • qint64 sendtextmessage(const qstring &message):发送文本消息。
    • qint64 sendbinarymessage(const qbytearray &data):发送二进制消息。
    • void ping(const qbytearray &payload = qbytearray()):发送ping帧。
  • 状态查询:

    • qabstractsocket::socketstate state() const:返回当前websocket连接的状态。
    • qurl requesturl() const:返回请求的url。
    • bool isvalid() const:判断websocket连接是否有效。

常用信号

以下是qwebsocket类中一些常用的信号及其简要介绍:

  • void connected():当websocket连接成功时发出信号。
  • void disconnected():当websocket连接断开时发出信号。
  • void textmessagereceived(const qstring &message):当接收到文本消息时发出信号。
  • void binarymessagereceived(const qbytearray &message):当接收到二进制消息时发出信号。
  • void error(qabstractsocket::socketerror error):当websocket连接发生错误时发出信号。
  • void statechanged(qabstractsocket::socketstate state):当websocket连接状态发生变化时发出信号。

💻示例代码

下面是一个简单的示例,用来演示如何使用qwebsocket实现websocket通信。该示例展示了一个带有按钮和文本编辑区域的窗口,点击按钮后可以连接到websocket服务器,并进行消息发送和接收。

示例:websocket客户端

#include <qapplication>
#include <qmainwindow>
#include <qwebsocket>
#include <qpushbutton>
#include <qvboxlayout>
#include <qlineedit>
#include <qtextedit>

class mainwindow : public qmainwindow
{
    q_object

public:
    mainwindow(qwidget *parent = nullptr) : qmainwindow(parent)
    {
        setwindowtitle("qwebsocket example");
        resize(400, 300);

        // 创建websocket对象
        websocket = new qwebsocket();

        // 创建ui组件
        qpushbutton *connectbutton = new qpushbutton("connect");
        qpushbutton *sendmessagebutton = new qpushbutton("send message");
        urllineedit = new qlineedit("ws://echo.websocket.org");
        messagelineedit = new qlineedit();
        messagetextedit = new qtextedit();
        messagetextedit->setreadonly(true);

        // 连接信号和槽
        connect(connectbutton, &qpushbutton::clicked, this, &mainwindow::connecttoserver);
        connect(sendmessagebutton, &qpushbutton::clicked, this, &mainwindow::sendmessage);
        connect(websocket, &qwebsocket::connected, this, &mainwindow::onconnected);
        connect(websocket, &qwebsocket::disconnected, this, &mainwindow::ondisconnected);
        connect(websocket, &qwebsocket::textmessagereceived, this, &mainwindow::ontextmessagereceived);

        // 布局管理
        qvboxlayout *layout = new qvboxlayout;
        layout->addwidget(urllineedit);
        layout->addwidget(connectbutton);
        layout->addwidget(messagelineedit);
        layout->addwidget(sendmessagebutton);
        layout->addwidget(messagetextedit);
        qwidget *centralwidget = new qwidget;
        centralwidget->setlayout(layout);

        setcentralwidget(centralwidget);
    }

private slots:
    void connecttoserver()
    {
        qurl url(urllineedit->text());
        websocket->open(url);
    }

    void sendmessage()
    {
        qstring message = messagelineedit->text();
        websocket->sendtextmessage(message);
    }

    void onconnected()
    {
        messagetextedit->append("websocket connected.");
    }

    void ondisconnected()
    {
        messagetextedit->append("websocket disconnected.");
    }

    void ontextmessagereceived(const qstring &message)
    {
        messagetextedit->append("received: " + message);
    }

private:
    qwebsocket *websocket;
    qlineedit *urllineedit;
    qlineedit *messagelineedit;
    qtextedit *messagetextedit;
};

int main(int argc, char *argv[])
{
    qapplication app(argc, argv);

    // 创建主窗口并显示
    mainwindow mainwindow;
    mainwindow.show();

    return app.exec();
}

#include "main.moc"

代码解释

  • 创建主窗口,并设置其标题和大小:

    mainwindow(qwidget *parent = nullptr) : qmainwindow(parent)
    {
        setwindowtitle("qwebsocket example");
        resize(400, 300);
    }
    
  • 创建qwebsocket对象:

    websocket = new qwebsocket();
    
  • 创建ui组件,包括按钮、文本输入框和文本编辑区域:

    qpushbutton *connectbutton = new qpushbutton("connect");
    qpushbutton *sendmessagebutton = new qpushbutton("send message");
    urllineedit = new qlineedit("ws://echo.websocket.org");
    messagelineedit = new qlineedit();
    messagetextedit = new qtextedit();
    messagetextedit->setreadonly(true);
    
  • 连接按钮和qwebsocket信号到槽函数:

    connect(connectbutton, &qpushbutton::clicked, this, &mainwindow::connecttoserver);
    connect(sendmessagebutton, &qpushbutton::clicked, this, &mainwindow::sendmessage);
    connect(websocket, &qwebsocket::connected, this, &mainwindow::onconnected);
    connect(websocket, &qwebsocket::disconnected, this, &mainwindow::ondisconnected);
    connect(websocket, &qwebsocket::textmessagereceived, this, &mainwindow::ontextmessagereceived);
    
  • 布局管理,将ui组件添加到窗口中央控件中:

    qvboxlayout *layout = new qvboxlayout;
    layout->addwidget(urllineedit);
    layout->addwidget(connectbutton);
    layout->addwidget(messagelineedit);
    layout->addwidget(sendmessagebutton);
    layout->addwidget(messagetextedit);
    qwidget *centralwidget = new qwidget;
    centralwidget->setlayout(layout);
    setcentralwidget(centralwidget);
    
  • 实现槽函数connecttoserver,连接到websocket服务器:

    void connecttoserver()
    {
        qurl url(urllineedit->text());
        websocket->open(url);
    }
    
  • 实现槽函数sendmessage,发送文本消息:

    void sendmessage()
    {
        qstring message = messagelineedit->text();
        websocket->sendtextmessage(message);
    }
    
  • 实现槽函数onconnected,处理websocket连接成功事件:

    void onconnected()
    {
        messagetextedit->append("websocket connected.");
    }
    
  • 实现槽函数ondisconnected,处理websocket连接断开事件:

    void ondisconnected()
    {
        messagetextedit->append("websocket disconnected.");
    }
    
  • 实现槽函数ontextmessagereceived,处理接收到的文本消息:

    void ontextmessagereceived(const qstring &message)
    {
        messagetextedit->append("received: " + message);
    }
    
  • 启动qt事件循环:

    return app.exec();
    

方法分析

  1. void open(const qurl &url):连接到指定的websocket服务器。

    void open(const qurl &url)
    

    用于连接到指定的websocket服务器。

  2. void close(qwebsocketprotocol::closecode closecode = qwebsocketprotocol::closecodenormal, const qstring &reason = qstring()):关闭websocket连接。

    void close(qwebsocketprotocol::closecode closecode = qwebsocketprotocol::closecodenormal, const qstring &reason = qstring())
    

    用于关闭websocket连接,可以选择指定关闭代码和原因。

  3. qint64 sendtextmessage(const qstring &message):发送文本消息。

    qint64 sendtextmessage(const qstring &message)
    

    用于发送指定的文本消息。

  4. qint64 sendbinarymessage(const qbytearray &data):发送二进制消息。

    qint64 sendbinarymessage(const qbytearray &data)
    

    用于发送指定的二进制消息。

  5. void ping(const qbytearray &payload = qbytearray()):发送ping帧。

    void ping(const qbytearray &payload = qbytearray())
    

    用于发送ping帧,可以选择指定负载数据。

  6. qabstractsocket::socketstate state() const:返回当前websocket连接的状态。

    qabstractsocket::socketstate state() const
    

    用于获取当前websocket连接的状态。

  7. qurl requesturl() const:返回请求的url。

    qurl requesturl() const
    

    用于获取请求的url。

  8. bool isvalid() const:判断websocket连接是否有效。

    bool isvalid() const
    

    用于判断websocket连接是否有效。

🧐注意事项

  1. 网络错误处理:在使用qwebsocket进行通信时,注意处理各种网络错误和异常情况,如连接失败、断开连接等。
  2. 线程安全:由于qwebsocket是一个i/o设备,操作qwebsocket对象时请确保线程安全,通常需要在主线程中进行操作。
  3. 资源管理:确保在合适的时机销毁qwebsocket对象,防止资源泄漏。
  4. 数据格式:在发送和接收数据时,注意数据格式的正确性,避免数据解析错误。

🛠️使用技巧

  1. 心跳检测:通过定期发送ping帧,实现心跳检测,确保websocket连接的稳定性。

    qtimer *heartbeattimer = new qtimer(this);
    connect(heartbeattimer, &qtimer::timeout, this, [this]() {
        websocket->ping();
    });
    heartbeattimer->start(30000); // 每30秒发送一次ping
    
  2. 连接状态监控:通过连接statechanged信号,实现对websocket连接状态的监控。

    connect(websocket, &qwebsocket::statechanged, this, [](qabstractsocket::socketstate state) {
        qdebug() << "websocket state changed:" << state;
    });
    
  3. 断线重连:在websocket连接断开时,尝试重连机制,提高通信的可靠性。

    connect(websocket, &qwebsocket::disconnected, this, [this]() {
        qtimer::singleshot(5000, this, [this]() {
            websocket->open(qurl("ws://echo.websocket.org"));
        });
    });
    
  4. ssl/tls加密:通过使用wss协议,实现ssl/tls加密通信,确保数据传输的安全性。

    websocket->open(qurl("wss://secure.websocket.org"));
    
  5. 二进制数据传输:通过sendbinarymessagebinarymessagereceived实现二进制数据的传输。

    qbytearray binarydata = ...; // 填充二进制数据
    websocket->sendbinarymessage(binarydata);
    
    connect(websocket, &qwebsocket::binarymessagereceived, this, [](const qbytearray &data) {
        qdebug() << "received binary data:" << data;
    });
    

📌总结

qwebsocket是qt提供的一个功能强大且灵活的websocket通信类,通过本篇文章的学习,你应该对qwebsocket有了全面的理解,能够在自己的项目中正确使用它。qwebsocket在用户界面中帮助你实现实时数据传输和消息推送,实现交互式和响应式的实时通信,有助于创建用户友好和高效的实时通信应用场景。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com