在使用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();
}