なぜチャットは一瞬で届くのか?リアルタイム通信「進化の歴史」を追う
🤖 本記事はAI(Claude)で下書きを作成し、筆者が全文を監修・検証したうえで公開しています。技術的な正確性は筆者が担保していますが、誤りを見つけた際はコメント等でご指摘いただけると幸いです。
記事の前に
今回、個人開発として歌を練習するためのアプリとして自分の声の高さを可視化するアプリを作りました。
その過程でリアルタイム通信をする必要が出てきたので、色々調べてみた結果をまとめます。
はじめに
LINEでメッセージを送ると、相手のスマホに一瞬で届く。Google Docsで同じファイルを開けば、他の人のカーソルがリアルタイムで動いているのが見える。Zoomでは顔も声も数百ミリ秒の遅延で相手に届く。
これら「リアルタイム通信」は、いまや当たり前の体験になりました。でも、Webの世界では本来、こういうことはできなかったんです。
Webの基本プロトコルであるHTTPは、「クライアントから聞かれたら、サーバーが答える」という片方向のキャッチボールが前提。サーバーから勝手に「おーい!」と話しかけることは、仕組み上できませんでした。
じゃあ、どうやって今の「即時に届く世界」を作ってきたのか?
この記事では、リアルタイム通信が30年かけてどう進化してきたのかを、ストーリー仕立てで追いかけます。次回の「WebSocket・SSE・WebRTC・ロングポーリング完全ガイド」の前提知識として、まずは歴史の流れを掴んでもらえると嬉しいです。
想定読者
この記事は、次のような方に向けて書いています。
- Web開発の経験が1〜3年目くらいで、これからリアルタイム通信に本格的に触れる方
- WebSocketやSSEという名前は聞いたことがあるけれど、違いや使い分けをうまく説明できない方
- チャット・通知・コラボツールなど、リアルタイム性が求められる機能を作ろうとしている方
- 「とりあえずWebSocket」で実装する前に、なぜその技術があるのかという背景を理解したい方
- HTTPの仕組みはざっくり知っているが、リアルタイム通信の全体像を整理したい方
逆に、以下はこの記事では扱いません(次回の完全ガイドで扱う予定です):
- 各プロトコルの詳細な実装方法・サンプルコード
- スケーリングやインフラ設計の具体的な指針
- 技術選定の判断フロー
「まずは地図を手に入れる」ための記事、と思って読んでもらえるとちょうどいいです。
前提知識としては、HTTPのリクエスト/レスポンスがなんとなく分かるくらいで十分読み進められるように書きました。
第1幕:HTTPは「リクエストしか受け付けない」
まず、出発点を確認しましょう。
1991年に誕生したHTTPは、当時のWebの目的──「文書を取ってくる」ことに最適化されていました。クライアントがリクエストを投げ、サーバーが返す。それで接続はおしまい。このステートレスで片方向な設計が、Webをシンプルに保ち、爆発的に普及させた立役者でもあります。
けれど、2000年代に入ると雲行きが変わってきます。メッセンジャー、チャット、オンラインゲーム、株価表示──「サーバー側で何か起きたら、すぐクライアントに教えてほしい」というニーズが出てきたからです。
HTTPは答えてくれません。クライアントから聞かれないと、何も言えない仕組みだから。
ポーリング──「定期的に聞きに行く」作戦
最初の答えは、シンプルで力技でした。
クライアントが数秒ごとにサーバーへ「何か新しいことあります?」と聞きに行く。
これが「ポーリング(Polling)」です。
setInterval(() => {
fetch('/api/messages/new')
.then(res => res.json())
.then(messages => showMessages(messages));
}, 3000); // 3秒ごと
実装は簡単。でも、問題もわかりやすい:
- ムダが多い:何もなくても毎回通信する
- 遅い:最大でポーリング間隔ぶん遅延する
- スケールしない:ユーザーが増えるとサーバーが悲鳴を上げる
「新着メールありますか?」を3秒ごとに聞きに来る同僚がいたら、仕事になりませんよね。サーバー側の気持ちです。
第2幕:ロングポーリング──「答えを出さずに待つ」発明
2000年代半ば、賢い人たちが気づきました。
「サーバーから話しかけられないなら、クライアントからの問い合わせへの返事を"意図的に遅らせれば"いいのでは?」
これが「ロングポーリング(Long Polling)」です。
仕組みはこう:
- クライアントがサーバーに問い合わせる
- サーバーは、何かイベントが起きるまで返事をしない(接続を握ったまま待つ)
- イベントが発生したら、そのタイミングで返事をする
- クライアントは返事を受け取ったら、すぐに次の問い合わせをする
この発想は、2006年頃にAlex Russell氏によって「Comet」と名付けられ、一気に広まりました。初期のGmailチャットをはじめ、多くのWebサービスがこの仕組みで擬似的なプッシュ通知を実現していた時代があります。
通常のポーリングより遅延は劇的に減り、ムダな通信も減る。でも完璧ではありません:
- HTTPコネクションを長時間握りっぱなし → サーバーのリソースを食う
- 双方向ではなく、あくまで「サーバー→クライアント」の一方通行の改善
- プロキシやロードバランサーとの相性問題
力技を洗練させた、過渡期の発明という位置づけです。
第3幕:SSE──「サーバーからの片道配信」を正式にサポート
2009年頃、HTML5の一部として**Server-Sent Events(SSE)**が登場します。
SSEは、サーバーからクライアントへの片方向ストリームを正式にWeb標準として定義したもの。ブラウザにはEventSourceというAPIが用意されていて、驚くほど簡単に使えます。
const source = new EventSource('/api/events');
source.onmessage = (event) => {
console.log('サーバーから届いた:', event.data);
};
サーバー側は、接続を維持しながら「イベントが起きたら書き込む」だけ。通知、株価配信、ライブスコア、進捗表示──サーバー→クライアントの一方通行で十分なユースケースなら、これで必要十分です。
実装もHTTPの上に素直に乗っているので、プロキシや既存のインフラとの相性も悪くありません。「ロングポーリングの正しい進化形」と考えると位置づけが分かりやすいと思います。
ただし、双方向通信はできない。チャットのように「こちらから送る」用途には、やはりもう一歩足りないのでした。
第4幕:WebSocket──双方向通信のパラダイムシフト(2011年)
そして2011年12月、ついにRFC 6455として標準化されたのがWebSocketです。
WebSocketは、仕組みからして従来と全然違います:
- まずHTTPで接続し、
Upgradeヘッダを使ってWebSocketへプロトコルを昇格する - 昇格後は、HTTPではなく専用の軽量プロトコルで通信
- TCPコネクションを張りっぱなしで、双方向にメッセージを送り合える
const ws = new WebSocket('wss://example.com/chat');
ws.onmessage = (event) => console.log('受信:', event.data);
ws.send('こんにちは'); // こちらからも送れる
これまでの「HTTPの上で工夫する」路線から、そもそも別プロトコルを使う路線への大きなジャンプ。チャット、オンラインゲーム、コラボツール──双方向リアルタイム通信の定番として、今に至るまで主役級の存在です。
ただ、WebSocketも万能ではありません。接続維持のコスト、水平スケーリングの難しさ、セッション管理、ファイアウォール越えの問題などはついて回ります。「とりあえずWebSocket」で始めて後悔するケースは、実は結構あります。
第5幕:WebRTC──サーバーを通さない、P2P通信
2011年にはもう一つ、別系統の革命が始まります。**WebRTC(Web Real-Time Communication)**です。
これまでの話はすべて「クライアント⇔サーバー」の通信でした。でも、ビデオ通話を考えてみてください。AさんからBさんへ映像を届けるのに、わざわざサーバーを経由したら遅いし、サーバー負荷も莫大です。
WebRTCは、ブラウザ同士で**ピアツーピア(P2P)**に直接通信する仕組みを標準化しました。音声・映像・任意のデータを、低遅延で直接やりとりできます。
- Google Meetの一部機能
- Discordのボイスチャット
- ブラウザ上のP2Pファイル共有(例:Snapdrop)
──これらの土台になっている技術です。
ただし、WebRTCは「接続を成立させるまで」が複雑で、シグナリングサーバー、STUN/TURNサーバーといった仕組みが必要になります。このへんは次回の完全ガイドで詳しく触れる予定です。
現代:HTTP/2、HTTP/3、そしてWebTransportへ
WebSocketとWebRTCで物語は完結──ではありません。Web標準は今も進化し続けています。
- HTTP/2(RFC 7540、2015年):単一接続で複数ストリームを多重化できるようになり、SSEの効率が大きく改善
- HTTP/3(RFC 9114、2022年):UDPベースのQUICプロトコル上で動作。パケットロスに強く、モバイル環境で接続が切り替わっても再接続が速い
- WebTransport(策定中):HTTP/3上で動く、WebSocketの後継候補と目される新技術。双方向・信頼性の選択・データグラム送信など、モダンな要件に応える設計
「WebSocketがあれば全部解決」ではなく、用途に応じた選択肢がどんどん増えているのが現代です。
まとめ──歴史を振り返ると見えてくるもの
ざっと振り返ると、こんな流れになります:
表で整理するとこうです:
| 時期 | 技術 | 要点 |
|---|---|---|
| 〜2000年代初頭 | ポーリング | 定期的に聞きに行く力技 |
| 2000年代半ば | ロングポーリング(Comet) | 答えを遅らせて疑似プッシュ |
| 2009年頃 | SSE | サーバー→クライアントの片方向を標準化 |
| 2011年 | WebSocket | 双方向通信を別プロトコルで実現 |
| 2011年〜 | WebRTC | P2Pでの超低遅延通信 |
| 2015年〜 | HTTP/2, HTTP/3, WebTransport | モダンな基盤への刷新 |
面白いのは、新しい技術が出ても、古い技術が消えるわけではないということ。ポーリングもロングポーリングもSSEも、今も現役で使われています。用途と制約に応じて「適切なものを選ぶ」のが、エンジニアの仕事になっているんですね。
次回は、この歴史を踏まえつつWebSocket・SSE・WebRTC・ロングポーリングの4つを技術的に深掘りし、どう選び、どう実装するかを完全ガイドとしてまとめます。
お楽しみに!