Spec-Zone.ru › Qt

Пример WebSocket-сервера

Описание

Пример echoserver реализует WebSocket-сервер, который эхом возвращает всё, что ему отправляется.

Код

Начинаем с создания QWebSocketServer (`new QWebSocketServer()`). После создания, мы прослушиваем все локальные сетевые интерфейсы (`QHostAddress::Any`) на указанном порту.

EchoServer::EchoServer(quint16 port, bool debug, QObject *parent) :
    QObject(parent),
    m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Echo Server"),
                                            QWebSocketServer::NonSecureMode, this)),
    m_debug(debug)
{
    if (m_pWebSocketServer->listen(QHostAddress::Any, port)) {
        if (m_debug)
            qDebug() << "Echoserver listening on port" << port;
        connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
                this, &EchoServer::onNewConnection);
        connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &EchoServer::closed);
    }
}

Если прослушивание прошло успешно, мы подключаем сигнал `newConnection()` к слоту `onNewConnection()`. Сигнал `newConnection()` будет сгенерирован всякий раз, когда новый клиент WebSocket подключится к нашему серверу.

void EchoServer::onNewConnection()
{
    QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();

    connect(pSocket, &QWebSocket::textMessageReceived, this, &EchoServer::processTextMessage);
    connect(pSocket, &QWebSocket::binaryMessageReceived, this, &EchoServer::processBinaryMessage);
    connect(pSocket, &QWebSocket::disconnected, this, &EchoServer::socketDisconnected);

    m_clients << pSocket;
}

При получении нового подключения, клиент QWebSocket извлекается (`nextPendingConnection()`), и к нашим слотам подключаются интересующие нас сигналы (`textMessageReceived()`, `binaryMessageReceived()` и `disconnected()`). Клиентский сокет запоминается в списке, на случай, если нам понадобится использовать его позже (в данном примере с ним ничего не делается).

void EchoServer::processTextMessage(QString message)
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
    if (m_debug)
        qDebug() << "Message received:" << message;
    if (pClient) {
        pClient->sendTextMessage(message);
    }
}

Всякий раз, когда срабатывает `processTextMessage()`, мы извлекаем отправителя и, если он валиден, отправляем обратно исходное сообщение (`sendTextMessage()`). То же самое делается с бинарными сообщениями.

void EchoServer::processBinaryMessage(QByteArray message)
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
    if (m_debug)
        qDebug() << "Binary Message received:" << message;
    if (pClient) {
        pClient->sendBinaryMessage(message);
    }
}

Единственное отличие заключается в том, что сообщение теперь является QByteArray, а не QString.

void EchoServer::socketDisconnected()
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
    if (m_debug)
        qDebug() << "socketDisconnected:" << pClient;
    if (pClient) {
        m_clients.removeAll(pClient);
        pClient->deleteLater();
    }
}

Всякий раз, когда сокет отключается, мы удаляем его из списка клиентов и удаляем сокет. Примечание: лучше использовать `deleteLater()` для удаления сокета.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/echoserver.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API