Qt WebSocket实现连接超时以及断网之后的反馈

在使用Qt WebSocket的过程中发现没有连接超时以及断网之后的通知(个人理解,如有错误可以评论留言,我也学习一下)

定义了一个WebSocketThread类进行数据的接收、发送,以及连接状态的信号发出,以下是我的源码

WebSocketThread.h

#ifndef WEBSOCKETTHREAD_H
#define WEBSOCKETTHREAD_H

#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QWebSocket>
#include <stdint.h>
#include <atomic>

class WebSocketThread:public QThread
{
    Q_OBJECT
public:
    enum WS_State{
        WS_Open = 0,
        Ws_Close,
        Ws_CreateFailed
    };

    WebSocketThread(QObject *parent = nullptr);
    ~WebSocketThread();
    static WebSocketThread& Instance();

    void setWebSocketTag(const QString& tag);
    void setWebSocketAddr(const QString& ip,int port);

    bool sendBinary(const std::vector<uint8_t>& message);
signals:
    void connectInfo(int info);
    void reciveMsg(QString msg);
    void reciveServerMsg(QString msg);

public slots:
    void stop();
    void send(const QString& msg);
    void send(const std::string& msg);
    void close();

protected:
    void run();

private:
    int _port;
    QString _str_ip;
    QString _str_tag;
    QWebSocket* _pWS;
    static WebSocketThread _instance;
    QMutex _mutex_string;
    QQueue<std::string> _queue_string;
    QMutex _mutex_vector;
    QQueue<std::vector<uint8_t>> _queue_binary;

    std::atomic<bool> _close_socket;
};

#endif // WEBSOCKETTHREAD_H

WebSocketThread.cpp

#include "WebSocketThread.h"
#include <QDebug>
#include <QDateTime>
#include <functional>
#include <QTimer>

#define QUEUE_MAX_SIZE  5
#define TIME_OUT_SOCKET 3000

WebSocketThread WebSocketThread::_instance;
WebSocketThread::WebSocketThread(QObject *parent):
    QThread(parent)
{
    _pWS = NULL;
    _close_socket = false;
}

WebSocketThread::~WebSocketThread()
{
}

WebSocketThread &WebSocketThread::Instance()
{
    return _instance;
}

void WebSocketThread::setWebSocketTag(const QString &tag)
{
    _str_tag = tag;
}

void WebSocketThread::setWebSocketAddr(const QString &ip, int port)
{
    _str_ip = ip;
    _port = port;
}

bool WebSocketThread::sendBinary(const std::vector<uint8_t> &message)
{
    bool res = false;
    if(_pWS&&_pWS->state() == QAbstractSocket::ConnectedState)
    {
        _mutex_vector.lock();
        if(_queue_binary.size()< QUEUE_MAX_SIZE)
        {
            _queue_binary.push_back(message);
            res = true;
        }
        _mutex_vector.unlock();
    }
    return res;
}

void WebSocketThread::stop()
{
    this->quit();
}

void WebSocketThread::send(const QString &msg)
{
    if(_pWS&&_pWS->state() == QAbstractSocket::ConnectedState)
    {
        _mutex_string.lock();
        _queue_string.push_back(msg.toStdString());
        _mutex_string.unlock();
    }
}

void WebSocketThread::send(const std::string &msg)
{
    if(_pWS&&_pWS->state() == QAbstractSocket::ConnectedState)
    {
        _mutex_string.lock();
        _queue_string.push_back(msg);
        _mutex_string.unlock();
    }
}

void WebSocketThread::close()
{
    if(_pWS&&_pWS->state() == QAbstractSocket::ConnectedState)
    {
        _close_socket=true;
    }
}

void WebSocketThread::run()
{
    bool send_create = true;
    if(!_pWS)
    {
        _pWS = new QWebSocket;
    }
    QTimer timer,timer_timeout,timer_ping;
    int ping_num = 0;
    QString web_addr = QString("ws://%1:%2/%3").arg(_str_ip).arg(_port).arg(_str_tag);

    QObject::connect(_pWS,&QWebSocket::pong,[&](quint64 elapsedTime, const QByteArray &payload){
        ping_num--;
    });
    QObject::connect(_pWS,&QWebSocket::connected,[&](){
//        LOGD<<"connected:"<<(_pWS->state() == QAbstractSocket::ConnectedState);
        send_create = false;
        timer.start(1);
        ping_num = 0;
        timer_ping.start(10000);
        timer_timeout.stop();
        emit connectInfo(WS_Open);
    });
    QObject::connect(_pWS,&QWebSocket::disconnected,[&](){
        timer.stop();
        timer_ping.stop();
        if(send_create)
        {
            emit connectInfo(Ws_CreateFailed);
        }
        else {
            emit connectInfo(Ws_Close);
        }
        _close_socket = false;
        send_create = true;
        sleep(1);
        web_addr = QString("ws://%1:%2/%3").arg(_str_ip).arg(_port).arg(_str_tag);
        _pWS->open(QUrl(web_addr));
        timer_timeout.start(TIME_OUT_SOCKET);
    });
    QObject::connect(_pWS,&QWebSocket::textMessageReceived,[&](const QString &message){
        //
        emit reciveMsg(message);
    });

    QObject::connect(&timer,&QTimer::timeout,[&](){
        if(_close_socket.load())
        {
            _pWS->close();
            return;
        }
        /** 字符流 */
        if (!_queue_string.empty())
        {
            std::string sMessage;
            _mutex_string.lock();
            if (!_queue_string.empty())
            {
                sMessage = _queue_string.front();
                _queue_string.pop_front();
            }
            else
            {
                _mutex_string.unlock();
                return;
            }
            _mutex_string.unlock();
            _pWS->sendTextMessage(QString::fromStdString(sMessage));
        }
        /** 二进制流 */
        if (!_queue_binary.empty())
        {
            std::vector<uint8_t> sMessage;
            _mutex_vector.lock();
            if (!_queue_binary.empty())
            {
                sMessage = _queue_binary.front();
                _queue_binary.pop_front();
            }
            else
            {
                _mutex_vector.unlock();
                return;
            }
            _mutex_vector.unlock();
            int send_ = _pWS->sendBinaryMessage(QByteArray((char*)&sMessage[0],sMessage.size()));
        }
    });
    QObject::connect(&timer_timeout,&QTimer::timeout,[&](){
        timer_timeout.stop();
        if(_pWS->state() == QAbstractSocket::ConnectingState)
        {
            emit _pWS->disconnected();
        }
    });
    QObject::connect(&timer_ping,&QTimer::timeout,[&](){
        if(ping_num>5)
        {
            emit _pWS->disconnected();
            return;
        }
        _pWS->ping("ping");
        ping_num++;
    });

    _pWS->open(QUrl(web_addr));
    timer_timeout.start(TIME_OUT_SOCKET);

    this->exec();
    _pWS->close();
    _pWS->deleteLater();
}

main.cpp

#include <QCoreApplication>
#include "WebSocketThread.h"
#include <QDebug>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    /** 此处使用自己的websocket server接口等做为测试 */
    QString cmd_1 = "{\"tag\":\"win\",\"request\":\"language\"}";
    WebSocketThread::Instance().setWebSocketAddr("192.168.1.182",10086);
    WebSocketThread::Instance().setWebSocketTag("win");
    QTimer timer;
    QObject::connect(&timer,&QTimer::timeout,[&](){WebSocketThread::Instance().send(cmd_1);});
    WebSocketThread::Instance().start();
    timer.start(1000);

    return a.exec();
}

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值