WebSocket 接続が 1006 で終了するときのデバッグ方法

Published: 2022/10/4


問題

WebSocket を使うアプリケーションを開発していると、上手く WebSocket サーバーに接続できないような設定になっている場合、接続先の url は合っているはずなのに、接続がクローズコード 1006 で終了してしまい、何が原因なのかがイマイチ分からない、という事象が発生する。

特に、 WebSocket サーバーは node.js アプリケーションで動いている場合が多く、かつ、 node.js アプリケーションはあまりログを出力しないものが多かったりするので、その原因を特定するまでにハマってしまったりする場合がある。(というか、ハマった)

また、例えば Chrome Dev Tool で(ブラウザから)対応しようにも、どうやら正常に接続が完了した場合にのみ、もろもろの情報が DevTool に共有される仕様になっているらしく、特に接続確立の失敗によって発生するクローズコードである 1006 の場合、表示される情報がいろいろ制限されていて、あまり助けにならなかったりする。

ソリューション: Wireshark

パケットキャプチャのツールである Wireshark を用いることで、ブラウザにおいて表示されていなかった、ネットワークレベルでのHTTP リクエストのメッセージたちを確認することで、デバッグが可能となる場合がある。 特に、 websocket 接続のための handshake までは、それが完了するまではただの HTTP 電文なので、そこで何かおかしなことが起きているのであれば、そこでそれを検知できる。 (例: WebSocket サーバーからのレスポンスが 101 Switching Protocol であるところが 404 になっている、など)

自分の場合、 firefox では問題なく ws://localhost:8080/foo に websocket 接続でき、 chrome だとそこに接続ができない問題が発生していた。

firefox で接続した場合の websocket handshake のリクエストとレスポンスの電文を、 firefox と chrome のそれぞれでどうなっていたかを見比べた結果、chrome では localhost は IPv6 で接続され、 firefox だと IPv4 で接続され、その接続経路の違いにより WebSocket サーバーが異なるレスポンスを返すことを突き止めたことにより、問題の原因の特定がなされた。


Tags: websocketwireshark