Detailed explanation of WebSocket, and using QWebSocket to implement server and client (including code examples)

Table of contents

1. Background of the birth of WebSocket

2. Features of WebSocket:

3. Introduction to WebSocket

4. WebSocket advantages

5. QWebSocket communication-client:

6. QWebSocket communication—server:


1. Background of the birth of WebSocket

In the early days, many websites used polling (also called short polling) in order to implement push technology.

Polling means that the browser sends HTTP requests to the server at regular intervals, and then the server returns the latest data to the client.

2. Features of WebSocket:

1) Built on the TCP protocol, server-side implementation is relatively easy;

2) It has good compatibility with HTTP protocol. The default ports are also 80 and 443.

And the handshake phase uses the HTTP protocol, so it is not easy to block during the handshake and can pass various HTTP proxy servers;

3) The data format is relatively lightweight, has low performance overhead, and efficient communication;

4) You can send text or binary data;

5) There is no origin restriction and the client can communicate with any server;

6) The protocol identifier is ws (or wss if encrypted), and the server address is the URL,

It looks like: ws://example.com:80/some/path.

3. Introduction to WebSocket

WebSocket is a network transport protocol that enables full-duplex communication over a single TCP connection and is located at the application layer of the OSI model;

4. WebSocket advantages

1) Less control overhead: After the connection is created, when data is exchanged between the server and the client, the packet header used for protocol control is relatively small;

2) Stronger real-time performance: Since the protocol is full-duplex, the server can proactively send data to the client at any time. Compared with HTTP requests, which need to wait for the client to initiate a request before the server can respond, the delay is significantly less;

3) Maintain the connection state: Unlike HTTP, WebSocket needs to create a connection first, which makes it a stateful protocol, and some state information can be omitted during subsequent communications;

4) Better binary support: WebSocket defines binary frames, which can handle binary content more easily than HTTP;

5) Can support extensions: WebSocket defines extensions, and users can extend the protocol and implement some customized sub-protocols.

Because WebSocket has the above advantages, it is widely used in fields such as instant messaging/IM, real-time audio and video, online education, and games.

5. QWebSocket communication-client:

Some main interfaces used: (main steps)

#include <QWebSocket>
QWebSocket* m_pDataRecvWS = new QWebSocket();
m_pDataRecvWS->open(QUrl("URL"));//形如:ws://example.com:80/some/path

//客户端发出请求后,服务器会处理发相应的信号:
//1、连接成功后
connected();

//2、连接失败
disconnected();

//3、收到数据
textMessageReceived();

//常用的函数--------------------------------------
//发送消息
sendTextMessage()

A simple example:

//例子
QTimer m_timer = new QTimer();//重连计时器
if (m_pDataRecvWS == nullptr)
{
   m_pDataRecvWS = new QWebSocket();
   connect(m_pDataRecvWS, &QWebSocket::disconnected, this, &WebSocketClient::slotOnDisConnected, Qt::AutoConnection);
   connect(m_pDataRecvWS, &QWebSocket::textMessageReceived, this, &WebSocketClient::slotOnTextReceived, Qt::AutoConnection);
   connect(m_pDataRecvWS, &QWebSocket::connected, this, &WebSocketClient::slotOnConnected, Qt::AutoConnection);
   connect(m_timer, QTimer::timeout, this, &WebSocketClient::slotReconnect, Qt::AutoConnection);
   m_pDataRecvWS->open(QUrl(m_strURL));
}

//连接成功-关闭重连的计时器
void WebSocketClient::slotOnConnected()
{
    m_bConnectStatus = true;
    m_timer->stop();
}

//连接失败-启动计时器准备重连
void WebSocketClient::slotOnDisConnected()
{
    m_bConnectStatus = false;
    m_timer->start(3000);/*-<当连接失败时,触发重连计时器,设置计数周期为3秒 */
}

//重连
void WebSocketClient::slotReconnect()
{
    m_pDataRecvWS->abort();
    m_pDataRecvWS->open(QUrl(m_strURL));
}

//收到消息
void WebSocketClient::slotOnTextReceived(const QString& msg)
{
   // todo
}


6. QWebSocket communication—server:

Some main interfaces used: (main steps)

//声明变量
QWebSocketServer *m_pWebSocketServer;
QList<QWebSocket *> m_clients;//保存连接的客户端
unsigned short mPort;//端口号
QString mServerName;//服务器名字

//1、创建服务器
m_pWebSocketServer = new QWebSocketServer(mServerName, QWebSocketServer::NonSecureMode, this);

//2、监听
m_pWebSocketServer->listen(QHostAddress::LocalHost, mPort);//端口号

//3、有新的连接,会发这个信号
connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &WebSocketServer::onNewConnection);


//4、获得新的客户端nextPendingConnection
void WebSocketServer::onNewConnection()
{
    auto pSocket = m_pWebSocketServer->nextPendingConnection();
    pSocket->setParent(this);
    connect(pSocket, &QWebSocket::textMessageReceived, this, &WebSocketServer::processMessage);
    connect(pSocket, &QWebSocket::disconnected, this, &WebSocketServer::socketDisconnected);
    m_clients << pSocket;//放进去客户端列表
}

//5、接收到信息
void WebSocketServer::processMessage(const QString &message)
{
    QWebSocket *pSender = qobject_cast<QWebSocket *>(sender());
    for (QWebSocket *pClient : qAsConst(m_clients))
    {
        emit processServerMessage(message);
        if (pClient != pSender) //don't echo message back to sender
            pClient->sendTextMessage(message);
    }
}

//6、断开连接
void WebSocketServer::socketDisconnected()
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
    QTextStream(stdout) << getIdentifier(pClient) << " disconnected!\n";
    if (pClient)
    {
        m_clients.removeAll(pClient);
        pClient->deleteLater();
    }
}

Guess you like

Origin blog.csdn.net/bigger_belief/article/details/130725799