Boost.Beast は Boost.Asio の上に実装された HTTP と WebSocket の C++ライブラリです。
WebSocket は 単一のTCPコネクション上に双方向通信のチャンネルを提供する 通信プロトコルです。 RFC 6455 として標準化されている。
プロトコルの概要は下記が分かりやすかった。
Boost の使い方は 下記を参考にした。
Github からサーバーとクライアントのサンプルコードを持ってきて、ビルドして実行する。
github: beast example websocket
すんなり動いた。
注意:
クライアントを実行すると下記のメッセージが出る。
Websocket.org は2021 年に閉鎖されたようだ。
Example websocket-client-sync echo.websocket.org 80 "Hello, world!"
JvaScript クライアントからの接続も試す。
ソースを読んでみる。
websocket_client_sync.cpp の概要は下記のとおり。
websocket::stream<tcp::socket> ws{ioc}; ws.handshake(host, "/"); ws.write(net::buffer(std::string(text))); ws.read(buffer); ws.close(websocket::close_code::normal);
ほとんどの処理がライブラリを呼び出すだけ。
実行時にトレースメッセージは出ないので、 何をやっているか、分からず。
ライブラリのソースを読んでみる。 これは難解。
ソースを読むのは諦める。
TCP通信のやり取りを tcpdum で調べてみる。
% sudo tcpdump port 8080 -ilo0 -X
最初はオープニングハンドシェイク。 これは文字列の通信なのでわかりやすい。
client -> server
GET / HTTP/1.1
Host: localhost:8090
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Key: eDxQqF7QCZTWqNzVlz+3rA==
Sec-WebSocket-Version: 13
User-Agent: Boost.Beast/330 websocket-client-coroserver-> client
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: > NSiZPAhtEb04lODMOG24M7QH9So=
Server: Boost.Beast/330 websocket-server-sync
次に text(文字列) のエコーバック ここはバイナリなので、該当箇所を見つけるのに苦労する。
client -> server
818d b636 a1ed fe53 cd81 d91a 819a d944 cd89
server-> client
810d 4865 6c6c 6f2c 2077 6f72 6c64 21
最後にクロージングハンドシェイク。
client -> server
8882 673a 0f22 64d2
server-> client
8802 03e8
バイナリの解読が面倒だが、 プロトコルとおりであることが理解できた。
サンプルコードを Github に公開した https://github.com/ohwada/MAC_cpp_Samples/tree/master/boost_beast/websocket_sync