リアルタイム通信について
リアルタイム通信・ストリーミングについてと、技術選定について
リアルタイム通信/ストリーミングを実現する方法について
WebSocket
チャットアプリ、オンラインゲーム、株価更新など。
普通のWebアプリなら、ほぼWebSocket一択。
サーバー中心(サーバーで状態を一元管理する方が楽&安全)で全員に配るような処理、不特定多数向けの通信に向いている。
常にサーバー経由。
サーバが中継するので、接続数増えるとサーバ負荷増える。→スケールアウト(サーバー増やす)で対応可能
後述の他の手段と比較するとバランス型と言える。
WebRTC
音声通話、ビデオ通話、対戦・FPSゲームなど。
実装が大変でサーバ構成も複雑。
超低遅延が必要な場合の選択肢。
WebSocketとは異なり、最初だけサーバー、その後は基本P2P(直通)
端末同士で最短距離でやり取りするような処理、ミリ秒単位の遅延を抑えたい時、1対1 / 少人数向けの通信に向いている。
配信先が増えるとP2Pの直接接続数も比例して増えてしまうので多数向けではない。
SSE(Server-Sent Events)
通知、ログ配信、進捗バー表示など。
一方向でいい場合は一番コスパがいい。
サーバー → クライアントの一方向通信で、HTTPのままストリーミング可能。
WebSocketよりシンプル。自動再接続。
クライアント → サーバーは別途HTTP必要で、双方向ではない。
1接続 = 1ストリーム(接続張りっぱなし)であり、バイナリ効率悪い(基本テキスト)のため動画みたいな大容量に不向きで、キャッシュもできないため、Youtube等には不向き。
ポーリング
クライアント側から定期的にAPIを叩くなどして更新有無をチェック メール、旧Twitter、ECサイトの注文ステータスなどに採用。
HTTPストリーミング
数秒単位で動画を分割して配信
Youtubeの場合:HLS / MPEG-DASH
CDNに乗せられ、キャッシュでき、スケールも無限に近いが、数秒遅延が発生する
独自UDP
既存のWeb技術ではリアルタイム性が不十分な場合に、独自URPプロトコルが用意される場合がある(後述)
リアルタイム性重視。その代わりに安定性を妥協
各種サービスでの利用例
基本は、
- メッセージ系 → WebSocket
- 通話系 → WebRTC
- 動画配信 → HTTPストリーミング
- ガチゲーム → UDP独自実装
LINE
WebSocket + WebRTC(併用)
- テキストチャット → WebSocket
- 通話(音声・ビデオ) → WebRTC
Slack
WebSocket + WebRTC(併用)
- 基本 → WebSocket
- 通話 → 内部的にWebRTC
Zoom / Google Meet / Microsoft Teams
WebRTC(+サーバー中継)
-
音声・映像 → WebRTC
-
接続制御 → WebSocketなど
※SFU(中継サーバー)使用
ChatGPT
SSE(Server Sent Events)
Youtube
HTTPストリーミング
- 動画(ライブ配信含む) → HLS / MPEG-DASH(HTTPベース) ※ コメント欄はWebSocket or SSE
安定性とスケーラビリティ優先のため、ライブ配信でも採用されている。 また、WebRTCは少人数向けのため不向き。
Apex Legends(FPSゲーム)
独自UDP
- ゲーム通信 → UDPベース独自プロトコル
技術選定時の判断フロー
※ 下記はあくまで参考
- ミリ秒単位の遅延が必要 → WebRTC/UDP
- 不特定多数(数千〜数百万)に同時配信する → HTTPストリーミング(HLS / DASH)
- 双方向通信が必要 → 更新頻度(秒単位 or それ以上)が高ければWebSocket、低ければポーリング
- サーバーからクライアントへの一方向 → 更新頻度は数秒以内ならSSE、数十秒〜分単位でOKならポーリング
- 上記以外 → WebSocket