自前WebSocket実装でブラウザがopcode:13でエラーになってしまう件の原因


C++で自前WebSocket鯖実装をしていて、ハンドシェイクまではうまくいって受信は出来るのに、なぜか送信が出来ないという問題にぶち当たっていました。

色々調べたところ、ハンドシェイク時に\r\nを一つ多く返していたのが原因でした。

コードを抜粋するとこんな感じ。

        http_response_header += "HTTP/1.1 101 Switching Protocols\r\n";
        http_response_header += "Upgrade: websocket\r\n";
        http_response_header += "Connection: Upgrade\r\n";
        http_response_header += "Sec-WebSocket-Accept: "+encoded_text+"\r\n";
        http_response_header += "\r\n\r\n";

正しくは

        http_response_header += "HTTP/1.1 101 Switching Protocols\r\n";
        http_response_header += "Upgrade: websocket\r\n";
        http_response_header += "Connection: Upgrade\r\n";
        http_response_header += "Sec-WebSocket-Accept: "+encoded_text+"\r\n";
        http_response_header += "\r\n";

です。

余計な\rがopcodeとして認識されてエラーになっていたってことみたいです。

最初はさっぱり原因が分からず涙目だったのですが、何とかたどり着くことが出来たのはChromeの開発者向け機能のおかげです。

Chromeで

chrome://net-internals/#events&q=type:SOCKET%20is:active

を開くと接続中のsocketの情報を見ることが出来ます。

Eventlog

送受信しているバイト数しか分かりませんが、確かにパケットが到着していると分かるので、原因の切り分けに使えます。

また、ディベロッパーツールのNetworkの項目にはWebSocket Framesというタブがあり、ブラウザ側のエラーログもここに表示されます。

Devtool

Unrecognized frame opcode: 13

これが表示されてくれたおかげであっさり調べがついたので、本当に助かりました。

Leave a Comment