友達が Twitter で「これはいい記事」ってシェアしてたので、英語だけどがんばって読んでみることにした。
といったものの、Google 翻訳にかけるだけで十分読めたのでそれで読んだ。(最近の機械翻訳すごい)
HTTP と 双方向通信、そして WebSocket へ
HTTP は最初そんなにリッチなアプリを想定してなかったので、双方向通信のための仕組みはなかった。 定期的にサーバーに通信する(ポーリング)ことで擬似的に実現していた。
そこで、WebSocket が登場した。
WebSocket プロトコルの概要
WebSocket protocol にアップグレードすると、handshake 後、双方向通信ができる。 ws:// は暗号化なし、wss:// が port 443 で暗号化あり
WebSocket はフレーム単位でデータを送受信する ws のフレームにはヘッダがあって、 fin, rsv, opcode など色々な情報が入っている。 次の fin がくるまでデータを連結して、fin がきたらひとつの塊の終わりと認識できる opcode はデータが text か binary か、、などが入ってる opcode には ping/pong も用意されてて、疎通確認に便利
handshake 完了、データの受信、エラーなどはすべて event で受け取れる
WebSocket と HTTP/2
WebSocket は HTTP/2 と似ているのだろうか?
HTTP/2 には server push というサーバー側からリソースを積極的に送る機能がある しかし、これはアプリレベルでの双方向通信ではない、 server push はリソースのみを web browser に通知するもので、アプリレベルの event は来ない
それとは別に、Server Side Event (SSE) というものがある これはサーバーからアプリ側にデータを送信できるもので、HTTP ベースに設計されているため、HTTP/2 にもよく合う。
これで双方向の通信ができる。 実際に、特定の用途では HTTP/2 + SSE のほうが WebSocket より最適。
どちらを使えばいいのか?
オンラインゲームのように低レイテンシを目的とするなら WebSocket の方が優れたパフォーマンスが出る。 しかし、WebSocket は 既存の HTTP とは異なる protocol にアップグレードするので、互換性の面ですこし不安。
firewall や load balancer といった類の多くが HTTP 向けに作られているので、HTTP ベースで双方向通信できる SSE は、scalability, security といった面で有利である。しかし、HTTP/2 + SSE はブラウザのサポート状況がまだあまり良くない(これから良くなっていくはずだけど)