赞
踩
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
#ifndef READERWEBSOCKETSERVER_H #define READERWEBSOCKETSERVER_H #include <QObject> #include "Singleton.h" // 回调函数,将websocket的结果抛给上层 typedef void(*recvMsgToSerial)(const QByteArray &byteArray); class WebsocketServerBase; class ReaderWebsocketServer : public QObject, public Singleton<ReaderWebsocketServer> { Q_OBJECT friend class Singleton<ReaderWebsocketServer>; public: explicit ReaderWebsocketServer(QObject *parent = 0); virtual ~ReaderWebsocketServer(); public: // 设置回调函数 void setCallBack(recvMsgToSerial pFunc, void* pUser = NULL); // 接收串口发来数据,转发给客户端 bool sendData(const QByteArray &byteArray); signals: //转发数据给客户端 void sigSendToAllClients(const QByteArray &data); private slots: //处理客户端发来的数据,转发给需要的地方 void slotProcessServerMessage(const QByteArray &data); private: WebsocketServerBase* m_pWsServer = nullptr; QThread* m_thdWsServer = nullptr; void* m_pUser; // 返回回调的对象 recvMsgToSerial m_pRecvMsgToSerial; // 回调 }; #endif // READERWEBSOCKETSERVER_H
改造后服务器的源文件:
#include "readerwebsocketserver.h" #include <QThread> #include <cstring> #include "websocketserverbase.h" ReaderWebsocketServer::ReaderWebsocketServer(QObject *parent) : QObject(parent) { m_thdWsServer = new QThread(); m_pWsServer = new WebsocketServerBase("reader", 9000); m_pWsServer->moveToThread(m_thdWsServer); connect(m_pWsServer, &WebsocketServerBase::sigProcessServerMessage, this, &ReaderWebsocketServer::slotProcessServerMessage); connect(this, &ReaderWebsocketServer::sigSendToAllClients, m_pWsServer, &WebsocketServerBase::slotSendToAllClients); connect(m_thdWsServer, &QThread::started, m_pWsServer, &WebsocketServerBase::slotStartServer); connect(m_thdWsServer, &QThread::finished, m_pWsServer, &WebsocketServerBase::deleteLater); connect(m_thdWsServer, &QThread::finished, m_thdWsServer, &WebsocketServerBase::deleteLater); m_thdWsServer->start(); } ReaderWebsocketServer::~ReaderWebsocketServer() { if(m_thdWsServer) { m_thdWsServer->quit(); m_thdWsServer->wait(); } if(m_pWsServer) { m_pWsServer->deleteLater(); } } void ReaderWebsocketServer::setCallBack(recvMsgToSerial pFunc, void *pUser) { if (nullptr != pFunc) m_pRecvMsgToSerial = pFunc; if (nullptr != pUser) m_pUser = pUser; } //接收串口发来数据,转发给客户端 bool ReaderWebsocketServer::sendData(const QByteArray &byteArray) { bool hadBnode = m_pWsServer->hadClients(); if (hadBnode) { emit sigSendToAllClients(byteArray); } } //处理客户端发来的数据,转发给需要的地方 void ReaderWebsocketServer::slotProcessServerMessage(const QByteArray &byteArray) { qDebug() << __FUNCTION__ ; m_pRecvMsgToSerial(byteArray); }
(1)首先创建了一个客户端的基类,主要实现了客户端的基本接口:
(2)在客户端基类上,封装一个具体使用的类:(外面可以直接使用这个类进行通讯)
这个类,主要是添加了QThread 和QTimer,QThread 创建一个子线程来进行服务器的开启,监听和接收数据,不会影响主线程的事件;QTimer主要是发心跳包,实现断开重连机制;
接收和发送的数据,以二进制为例
(1)客户端基类:
客户端基类的头文件:
/* * @Description: websocket客户端,用于与中间件通信 */ #pragma once #include <QObject> #include <QByteArray> class QTimer; class QWebSocket; class WebSocketBase : public QObject { Q_OBJECT public: WebSocketBase(QObject *parent = nullptr); ~WebSocketBase(); void setWebSocketUrl(QString strUrl=""); bool getConnectStatus(); int RecvFrom(QByteArray& byteArray); signals: void sigClientBinaryMessageReceived(const QByteArray &byteArray); //借用websocket的信号函数 public slots: void slotCreateDataRecWS();//创建websocket连接 void slotSendBinaryMessageMessage(const QByteArray &byteArray); void slotReconnect(); /*-<周期重连函数 */ void slotActiveReconnect(); private slots: void slotOnConnected(); /*-<socket建立成功后,触发该函数 */ void slotOnBinaryMessageReceived(const QByteArray &byteArray); /*-<收到Sev端的数据时,触发该函数 */ void slotOnDisConnected(); /*-<socket连接断开后,触发该函数 */ private: QWebSocket *m_pDataRecvWS; /*-<websocket类 */ QTimer *m_pTimer; /*-<周期重连Timer */ QString m_strURL; /*连接URL*/ bool m_bConnectStatus; /*-<websocket连接状态,连接成功:true;断开:false */ QByteArray m_byteArray; };
客户端基类的源文件:
#include "WebSocketBase.h" #include <QWebSocket> #include <QTimer> #include <QByteArray> #include <cstring> WebSocketBase::WebSocketBase(QObject *parent) : QObject(parent) ,m_pDataRecvWS(nullptr) ,m_pTimer(nullptr) ,m_strURL("") ,m_bConnectStatus(false) ,m_byteArray("") { } WebSocketBase::~WebSocketBase() { m_pTimer->stop(); m_pTimer->deleteLater(); m_pDataRecvWS->abort(); m_pDataRecvWS->deleteLater(); } void WebSocketBase::setWebSocketUrl(QString strUrl) { m_strURL = strUrl; if(m_strURL.isEmpty()) { m_strURL = "127.0.0.1"; } } bool WebSocketBase::getConnectStatus() { return m_bConnectStatus; } int WebSocketBase::RecvFrom(QByteArray &byteArray) { byteArray = m_byteArray; m_byteArray.clear(); return byteArray.size(); } void WebSocketBase::slotCreateDataRecWS() { if(nullptr == m_pTimer) { m_pTimer = new QTimer(); } qDebug() << "Server Address" << m_strURL; if(m_pDataRecvWS == nullptr) { m_pDataRecvWS = new QWebSocket(); connect(m_pDataRecvWS, &QWebSocket::disconnected, this, &WebSocketBase::slotOnDisConnected); connect(m_pDataRecvWS, &QWebSocket::binaryMessageReceived, this, &WebSocketBase::slotOnBinaryMessageReceived); connect(m_pDataRecvWS, &QWebSocket::connected, this, &WebSocketBase::slotOnConnected); connect(m_pTimer, &QTimer::timeout, this, &WebSocketBase::slotReconnect); m_pDataRecvWS->open(QUrl(m_strURL)); } } void WebSocketBase::slotSendBinaryMessageMessage(const QByteArray &message) { if (m_pDataRecvWS) m_pDataRecvWS->sendBinaryMessage(message); } void WebSocketBase::slotActiveReconnect() { qDebug("try to Active Reconnect!!!"); if(m_pDataRecvWS != nullptr) { m_bConnectStatus = false; m_pDataRecvWS->abort(); qDebug("Exec Active Reconnect!"); m_pDataRecvWS->open(QUrl(m_strURL)); } return; } void WebSocketBase::slotReconnect() { qDebug() << "try to reconnect:" << m_strURL; m_pDataRecvWS->abort(); m_pDataRecvWS->open(QUrl(m_strURL)); } void WebSocketBase::slotOnConnected() { qDebug("WebSocketBase websocket is already connect!"); m_bConnectStatus = true; m_pTimer->stop(); qDebug() << "Address:" << m_strURL; } void WebSocketBase::slotOnDisConnected() { qDebug() << "Address is disconnected:" << m_strURL; m_bConnectStatus = false; m_pTimer->start(3000);/*-<当连接失败时,触发重连计时器,设置计数周期为3秒 */ } void WebSocketBase::slotOnBinaryMessageReceived(const QByteArray& byteArray) { m_byteArray = byteArray; }
(2)将客户端基类封装,改造下:(外面可以直接使用这个类进行通讯)
改造后客户端头文件:
/* * @Description: websocket客户端,用于与中间件通信 */ #pragma once #include <QObject> #include <QCoreApplication> #include "Singleton.h" class WebSocketBase; class QTimer; class WsReaderClient : public QObject, public Singleton<WsReaderClient> { Q_OBJECT friend class Singleton<WsReaderClient>; public: WsReaderClient(QObject *parent = nullptr); ~WsReaderClient(); public: void SendTo(const QByteArray &byteArray); int RecvFrom(QByteArray& byteArray); bool getConnectStatus(); signals: //转发数据给server void sigSendToServer(const QByteArray &byteArray); public slots: //接收服务器数据 void slotRecvServerData(const QByteArray &byteArray); //发送服务器心跳包 void slotHeartBeatToServer(); private: void readConfig(); private: WebSocketBase* m_wsReaderClient; QThread* m_thdReaderClient; QTimer *m_pTimerReader; int m_nHeartBeatTimeOutReader; QString m_URL = ""; };
改造后客户端源文件:
#include "WsReaderClient.h" #include <QWebSocket> #include <QTimer> #include <QThread> #include <QByteArray> #include <cstring> #include <QSettings> #include "WebSocketBase.h" WsReaderClient::WsReaderClient(QObject *parent) : QObject(parent) { readConfig(); m_thdReaderClient = new QThread(); m_wsReaderClient = new WebSocketBase(); m_wsReaderClient->setWebSocketUrl(m_URL); m_wsReaderClient->moveToThread(m_thdReaderClient); connect(m_thdReaderClient, &QThread::started, m_wsReaderClient, &WebSocketBase::slotCreateDataRecWS); connect(this, &WsReaderClient::sigSendToServer, m_wsReaderClient, &WebSocketBase::slotSendBinaryMessageMessage); //connect(this, &WsReaderClient::sigReconnectServer, m_wsReaderClient, &WebSocketBase::slotActiveReconnect); connect(m_thdReaderClient, &QThread::finished, m_wsReaderClient, &WebSocketBase::deleteLater); connect(m_thdReaderClient, &QThread::finished, m_thdReaderClient, &QThread::deleteLater); m_thdReaderClient->start(); m_pTimerReader = new QTimer(this); connect(m_pTimerReader, &QTimer::timeout, this, &WsReaderClient::slotHeartBeatToServer); //m_nHeartBeatTimeOutKeyBoard = 0; m_pTimerReader->start(10*1000); } WsReaderClient::~WsReaderClient() { m_pTimerReader->stop(); m_pTimerReader->deleteLater(); if(m_wsReaderClient) { delete m_wsReaderClient; m_wsReaderClient = nullptr; } if(m_pTimerReader) { delete m_pTimerReader; m_pTimerReader = nullptr; } } void WsReaderClient::slotHeartBeatToServer() { //todo } void WsReaderClient::readConfig() { // "/mnt/hgfs/SharedFiles/shanxi/Reader/linux_readerTest/bin/libReaderApi.so"; QString appPath = QCoreApplication::applicationDirPath(); qDebug() << "appPath=" << appPath; QString path = appPath + "/ReaderConfig.ini"; QSettings settings(path, QSettings::IniFormat); m_URL = settings.value("Communication/ipAddr").toString(); qDebug() << "m_URL=" << m_URL; } void WsReaderClient::SendTo(const QByteArray &data) { ![img](https://img-blog.csdnimg.cn/img_convert/987dc266e4a1d080e8c72b03d9fd63e5.png) ![img](https://img-blog.csdnimg.cn/img_convert/8e6df77be441cf534973b82c525f2767.png) **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。** **[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)** **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!** .value("Communication/ipAddr").toString(); qDebug() << "m_URL=" << m_URL; } void WsReaderClient::SendTo(const QByteArray &data) { [外链图片转存中...(img-1SnvAcTr-1715892724151)] [外链图片转存中...(img-MFHdXWD6-1715892724151)] **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。** **[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)** **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。