Deep dive into WebSockets and HTTP/2 with SSE を読んだメモ

友達が Twitter で「これはいい記事」ってシェアしてたので、英語だけどがんばって読んでみることにした。

といったものの、Google 翻訳にかけるだけで十分読めたのでそれで読んだ。(最近の機械翻訳すごい)

blog.sessionstack.com

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 はブラウザのサポート状況がまだあまり良くない(これから良くなっていくはずだけど)