网站加速器手机版,潜江资讯网手机版官网,新乡网站设计公司,设计手绘目录
前言
一、服务器的代码#xff1a;
1、服务器的思路
2、具体服务器的代码示例
二、客户端的代码#xff1a;
1、客户端的思路#xff08;和服务器类似#xff09;
2、具体客户端的代码示例 前言 要是想了解QWebSocket的详细知识#xff0c;还得移步到上一篇文…目录
前言
一、服务器的代码
1、服务器的思路
2、具体服务器的代码示例
二、客户端的代码
1、客户端的思路和服务器类似
2、具体客户端的代码示例 前言 要是想了解QWebSocket的详细知识还得移步到上一篇文章
WebSocket 详解以及用QWebSocket 实现服务端和客户端含代码例子-CSDN博客WebSocket 详解以及用QWebSocket 实现服务端和客户端含代码例子-CSDN博客 本篇文章主要讲解如何利用QWebSocket 实现服务和客户之间的通讯 一、服务器的代码
1、服务器的思路
1首先创建了一个服务器的基类主要实现了服务类的基本接口 1、创建服务器new QWebSocketServer 2、监听listen m_pWebSocketServer-listen(QHostAddress::LocalHost, mPort);//端口号 3、有新的连接收到这个信号QWebSocketServer::newConnection 4、获得新的客户端nextPendingConnection 5、接收到信息时候收到信号QWebSocket::binaryMessageReceived 6、断开连接收到信号QWebSocket::disconnected 注意数据的接收和发送有两种格式二进制和文本的具体按照实际需要的来选择 2在服务器的基类上封装一个具体使用的类这个类主要是添加了QThread创建一个子线程来进行服务器的开启监听和接收数据不会影响主线程的事件。
2、具体服务器的代码示例 接收和发送的数据以二进制为例
1服务器基类
服务器基类的头文件 1开启一个端口号为“9000”的服务器 2监听的网路是QHostAddress::Any QHostAddress::Any表示服务端监听所有可用的网络接口。 它是一个特殊的IP地址表示服务端可以接受来自任何IP地址的连接请求。 这通常用于在一个计算机上运行多个网络服务时让服务端能够监听所有可用的网络接口 以便接受来自不同网络接口的连接请求。 注意也可以监听具体的IP地址 例如QHostAddress(strLocalHostIp) #ifndef WEBSOCKETSERVERBASE_H
#define WEBSOCKETSERVERBASE_H#include QObject
#include QtWebSocketsQT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)
QT_FORWARD_DECLARE_CLASS(QString)class WebsocketServerBase : public QObject
{Q_OBJECT
public:explicit WebsocketServerBase(QString serverName, quint16 port, QObject *parent 0);virtual ~WebsocketServerBase();signals://客户端发来的数据void sigProcessServerMessage(const QByteArray data);public slots://发送数据给客户端void slotSendToAllClients(const QByteArray data);//启动websocket服务器void slotStartServer();private slots://处理新接入的连接void slotNewConnection();//处理链接断开的事件void slotSocketDisconnected();//接收数据并转发void slotProcessBinaryMessage(const QByteArray message);public://检测是否存在客户端bool hadClients();private:QWebSocketServer *m_pWebSocketServer nullptr;QListQWebSocket * m_clients;unsigned short m_nPort 9000;QString m_strServerName server;
};#endif // WEBSOCKETSERVERBASE_H服务器基类的源文件
#include websocketserverbase.h#includeQDebugstatic QString getIdentifier(QWebSocket *peer)
{return QStringLiteral(%1:%2).arg(peer-peerAddress().toString(),peer-origin());
}WebsocketServerBase::WebsocketServerBase(QString serverName, quint16 port, QObject *parent): QObject(parent),m_nPort(port),m_strServerName(serverName)
{
}WebsocketServerBase::~WebsocketServerBase()
{ if(m_pWebSocketServer){m_pWebSocketServer-close();//m_pWebSocketServer-abort();m_pWebSocketServer-deleteLater();}
}//接收到外部发来的信息转发给客户端
void WebsocketServerBase::slotSendToAllClients(const QByteArray data)
{qDebug() __FUNCTION__;for (QWebSocket *pClient : qAsConst(m_clients)) {qDebug() data: data;pClient-sendBinaryMessage(data);}
}bool WebsocketServerBase::hadClients()
{return m_clients.size()0;
}void WebsocketServerBase::slotStartServer()
{if(m_pWebSocketServer)return;m_pWebSocketServer new QWebSocketServer(m_strServerName, QWebSocketServer::NonSecureMode, this);if (m_pWebSocketServer-listen(QHostAddress::Any, m_nPort)){connect(m_pWebSocketServer, QWebSocketServer::newConnection, this, WebsocketServerBase::slotNewConnection);qDebug() WebSocket is start, port: m_nPort;}
}void WebsocketServerBase::slotNewConnection()
{auto pSocket m_pWebSocketServer-nextPendingConnection();QTextStream(stdout) getIdentifier(pSocket) connected!\n;qDebug() client connected!;pSocket-setParent(this);//二进制数据的接收connect(pSocket, QWebSocket::binaryMessageReceived, this, WebsocketServerBase::slotProcessBinaryMessage);connect(pSocket, QWebSocket::disconnected, this, WebsocketServerBase::slotSocketDisconnected);m_clients pSocket;
}void WebsocketServerBase::slotSocketDisconnected()
{QWebSocket *pClient qobject_castQWebSocket *(sender());QTextStream(stdout) getIdentifier(pClient) disconnected!\n;if (pClient){m_clients.removeAll(pClient);pClient-deleteLater();}
}//接收客户端发来的数据并转发出去
void WebsocketServerBase::slotProcessBinaryMessage(const QByteArray data)
{qDebug() __FUNCTION__ data: data;emit sigProcessServerMessage(data);//test//slotSendToAllClients(data);
}2将服务器基类封装改造下外面可以直接使用这个类进行通讯
改造后服务器的头文件 此处本例是使用回调函数将结果抛给上一层调用者在qt里完全可以用信号槽代替的。
#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 SingletonReaderWebsocketServer
{Q_OBJECTfriend class SingletonReaderWebsocketServer;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.hReaderWebsocketServer::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、客户端的思路和服务器类似
1首先创建了一个客户端的基类主要实现了客户端的基本接口
2在客户端基类上封装一个具体使用的类外面可以直接使用这个类进行通讯 这个类主要是添加了QThread 和QTimerQThread 创建一个子线程来进行服务器的开启监听和接收数据不会影响主线程的事件QTimer主要是发心跳包实现断开重连机制
2、具体客户端的代码示例 接收和发送的数据以二进制为例
1客户端基类
客户端基类的头文件
/** Description: websocket客户端用于与中间件通信*/#pragma once
#include QObject
#include QByteArrayclass 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 cstringWebSocketBase::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.hclass WebSocketBase;
class QTimer;class WsReaderClient : public QObject, public SingletonWsReaderClient
{Q_OBJECTfriend class SingletonWsReaderClient;public:WsReaderClient(QObject *parent nullptr);~WsReaderClient();public:void SendTo(const QByteArray byteArray);int RecvFrom(QByteArray byteArray);bool getConnectStatus();signals://转发数据给servervoid 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.hWsReaderClient::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)
{emit sigSendToServer(data);
}int WsReaderClient::RecvFrom(QByteArray byteArray)
{return m_wsReaderClient-RecvFrom(byteArray);
}bool WsReaderClient::getConnectStatus()
{return m_wsReaderClient-getConnectStatus();
} 文章转载自: http://www.morning.kgphd.cn.gov.cn.kgphd.cn http://www.morning.xqcbz.cn.gov.cn.xqcbz.cn http://www.morning.plhyc.cn.gov.cn.plhyc.cn http://www.morning.ggmls.cn.gov.cn.ggmls.cn http://www.morning.wgcng.cn.gov.cn.wgcng.cn http://www.morning.sldrd.cn.gov.cn.sldrd.cn http://www.morning.coatingonline.com.cn.gov.cn.coatingonline.com.cn http://www.morning.qzpkr.cn.gov.cn.qzpkr.cn http://www.morning.nba1on1.com.gov.cn.nba1on1.com http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn http://www.morning.rdlxh.cn.gov.cn.rdlxh.cn http://www.morning.mlnzx.cn.gov.cn.mlnzx.cn http://www.morning.ggnkt.cn.gov.cn.ggnkt.cn http://www.morning.qqnh.cn.gov.cn.qqnh.cn http://www.morning.kqylg.cn.gov.cn.kqylg.cn http://www.morning.lkgqb.cn.gov.cn.lkgqb.cn http://www.morning.hrqfl.cn.gov.cn.hrqfl.cn http://www.morning.ddjp.cn.gov.cn.ddjp.cn http://www.morning.pcngq.cn.gov.cn.pcngq.cn http://www.morning.drswd.cn.gov.cn.drswd.cn http://www.morning.hhrpy.cn.gov.cn.hhrpy.cn http://www.morning.zrgx.cn.gov.cn.zrgx.cn http://www.morning.ggcjf.cn.gov.cn.ggcjf.cn http://www.morning.qbfs.cn.gov.cn.qbfs.cn http://www.morning.mkpkz.cn.gov.cn.mkpkz.cn http://www.morning.cczrw.cn.gov.cn.cczrw.cn http://www.morning.jhwwr.cn.gov.cn.jhwwr.cn http://www.morning.bzjpn.cn.gov.cn.bzjpn.cn http://www.morning.kxyqy.cn.gov.cn.kxyqy.cn http://www.morning.hhxpl.cn.gov.cn.hhxpl.cn http://www.morning.qscsy.cn.gov.cn.qscsy.cn http://www.morning.pfjbn.cn.gov.cn.pfjbn.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn http://www.morning.jkdtz.cn.gov.cn.jkdtz.cn http://www.morning.stlgg.cn.gov.cn.stlgg.cn http://www.morning.kryxk.cn.gov.cn.kryxk.cn http://www.morning.hsdhr.cn.gov.cn.hsdhr.cn http://www.morning.ljhnn.cn.gov.cn.ljhnn.cn http://www.morning.zhmgcreativeeducation.cn.gov.cn.zhmgcreativeeducation.cn http://www.morning.xqcgb.cn.gov.cn.xqcgb.cn http://www.morning.mbpfk.cn.gov.cn.mbpfk.cn http://www.morning.yfzld.cn.gov.cn.yfzld.cn http://www.morning.ohmyjiu.com.gov.cn.ohmyjiu.com http://www.morning.nqlnd.cn.gov.cn.nqlnd.cn http://www.morning.rrwft.cn.gov.cn.rrwft.cn http://www.morning.ntlxg.cn.gov.cn.ntlxg.cn http://www.morning.bpmfz.cn.gov.cn.bpmfz.cn http://www.morning.wkmyt.cn.gov.cn.wkmyt.cn http://www.morning.zxqyd.cn.gov.cn.zxqyd.cn http://www.morning.kjrlp.cn.gov.cn.kjrlp.cn http://www.morning.nnttr.cn.gov.cn.nnttr.cn http://www.morning.kwblwbl.cn.gov.cn.kwblwbl.cn http://www.morning.wnrcj.cn.gov.cn.wnrcj.cn http://www.morning.xymkm.cn.gov.cn.xymkm.cn http://www.morning.kjkml.cn.gov.cn.kjkml.cn http://www.morning.cylbs.cn.gov.cn.cylbs.cn http://www.morning.rdbj.cn.gov.cn.rdbj.cn http://www.morning.tbknh.cn.gov.cn.tbknh.cn http://www.morning.zhghd.cn.gov.cn.zhghd.cn http://www.morning.rtkgc.cn.gov.cn.rtkgc.cn http://www.morning.mhlkc.cn.gov.cn.mhlkc.cn http://www.morning.jxzfg.cn.gov.cn.jxzfg.cn http://www.morning.kzhxy.cn.gov.cn.kzhxy.cn http://www.morning.hwnnm.cn.gov.cn.hwnnm.cn http://www.morning.bnxnq.cn.gov.cn.bnxnq.cn http://www.morning.dhckp.cn.gov.cn.dhckp.cn http://www.morning.mytmx.cn.gov.cn.mytmx.cn http://www.morning.sdkaiyu.com.gov.cn.sdkaiyu.com http://www.morning.phxns.cn.gov.cn.phxns.cn http://www.morning.fnwny.cn.gov.cn.fnwny.cn http://www.morning.syglx.cn.gov.cn.syglx.cn http://www.morning.lchtb.cn.gov.cn.lchtb.cn http://www.morning.qynnw.cn.gov.cn.qynnw.cn http://www.morning.zmwzg.cn.gov.cn.zmwzg.cn http://www.morning.pftjj.cn.gov.cn.pftjj.cn http://www.morning.tturfsoc.com.gov.cn.tturfsoc.com http://www.morning.dwfzm.cn.gov.cn.dwfzm.cn http://www.morning.rwnx.cn.gov.cn.rwnx.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.hnzrl.cn.gov.cn.hnzrl.cn