cpp-httplibはWebSocketにも対応しています。HTTPのリクエスト/レスポンスと違い、WebSocketはサーバーとクライアントが双方向にメッセージをやり取りできます。チャットやリアルタイム通知に便利です。
さっそく、エコーサーバーとクライアントを作ってみましょう。
受け取ったメッセージをそのまま返すエコーサーバーです。
#include "httplib.h" #include <iostream> int main() { httplib::Server svr; svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) { std::string msg; while (ws.read(msg)) { ws.send(msg); // 受け取ったメッセージをそのまま返す } }); std::cout << "Listening on port 8080..." << std::endl; svr.listen("0.0.0.0", 8080); }
svr.WebSocket() でWebSocketハンドラーを登録します。3章の svr.Get() や svr.Post() と同じ感覚ですね。
ハンドラーの中では、ws.read(msg) でメッセージを待ちます。接続が閉じられると read() が false を返すので、ループを抜けます。ws.send(msg) でメッセージを送り返します。
httplib::ws::WebSocketClient を使ってサーバーに接続してみましょう。
#include "httplib.h" #include <iostream> int main() { httplib::ws::WebSocketClient client("ws://localhost:8080/ws"); if (!client.connect()) { std::cout << "Connection failed" << std::endl; return 1; } // メッセージを送信 client.send("Hello, WebSocket!"); // サーバーからの応答を受信 std::string msg; if (client.read(msg)) { std::cout << msg << std::endl; // Hello, WebSocket! } client.close(); }
コンストラクタには ws://host:port/path 形式のURLを渡します。connect() で接続を開始し、send() と read() でメッセージをやり取りします。
WebSocketにはテキストとバイナリの2種類のメッセージがあります。read() の戻り値で区別できます。
svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) { std::string msg; httplib::ws::ReadResult ret; while ((ret = ws.read(msg))) { if (ret == httplib::ws::Binary) { ws.send(msg.data(), msg.size()); // バイナリとして送信 } else { ws.send(msg); // テキストとして送信 } } });
ws.send(const std::string &) — テキストメッセージとして送信ws.send(const char *, size_t) — バイナリメッセージとして送信クライアント側も同じAPIです。
ハンドラーの第1引数 req から、ハンドシェイク時のHTTPリクエスト情報を読み取れます。認証トークンの確認などに便利です。
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) { auto token = req.get_header_value("Authorization"); if (token.empty()) { ws.close(httplib::ws::CloseStatus::PolicyViolation, "unauthorized"); return; } std::string msg; while (ws.read(msg)) { ws.send(msg); } });
HTTPS上のWebSocket(WSS)にも対応しています。サーバー側は httplib::SSLServer にWebSocketハンドラーを登録するだけです。
httplib::SSLServer svr("cert.pem", "key.pem"); svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) { std::string msg; while (ws.read(msg)) { ws.send(msg); } }); svr.listen("0.0.0.0", 8443);
クライアント側は wss:// スキームを使います。
httplib::ws::WebSocketClient client("wss://localhost:8443/ws");
WebSocketの基本がわかりましたね。ここまでで Tourは終わりです。
次のページでは、Tourで取り上げなかった機能をまとめて紹介します。
次: What's Next