WebSocketサーバーの例
説明
echoserver のサンプルは、送られてきたものをすべてエコーバックする WebSocket サーバーを実装しています。
コード
まず、QWebSocketServer (`new QWebSocketServer()`) を作成します。作成後、指定したport 上のすべてのローカルネットワークインタフェース (`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()` スロットに接続します。新しい WebSocket クライアントがサーバーに接続されると、 `newConnection()` シグナルがスローされます。
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); } }
唯一の違いは、メッセージがQString ではなくQByteArray になったことです。
void EchoServer::socketDisconnected() { QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); if (m_debug) qDebug() << "socketDisconnected:" << pClient; if (pClient) { m_clients.removeAll(pClient); pClient->deleteLater(); } }
ソケットが切断されるたびに、クライアントリストからソケットを削除する。注意: ソケットの削除には `deleteLater()` を使うのがよい。
本ドキュメントに含まれる文書の著作権はそれぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。