SSE・WebSocketとは?サーバープッシュ技術の仕組みと使い分けをわかりやすく解説

元記事を読む
キュレーターコメント

35歳未経験転職という実体験から書かれた入門記事で、抽象的になりがちなサーバープッシュの概念をアナロジーで丁寧に整理している点が秀逸。ChatGPTのストリーミング表示やリアルタイムチャットの仕組みを「なぜそうなるのか」から理解したい方に特に刺さる内容だ。

概要

LINEやSlackでメッセージが届いたとき、画面を更新しなくても「ポン」と表示される。株価アプリでリアルタイムに数値が変わる。ChatGPTの回答が少しずつ流れるように表示される——これらはすべて サーバープッシュ技術 によって実現されている。

「WebSocket」「SSE」という単語を見て苦手意識を感じたことがある人も多いはず。この記事では、その2つの技術の仕組みと違い、そして「どちらを使えばいいか」を整理する。

従来のHTTP通信の限界

通常のWeb通信(HTTP)は リクエスト・レスポンス の一問一答だ。ブラウザが「くれ」と言ったらサーバーが「はい」と返し、そこで接続は切れる。

これでは「新着メッセージを受け取る」ためにブラウザが定期的にサーバーへ問い合わせ続けるしかない(ポーリング)。秒単位でリクエストを飛ばせばサーバー負荷は跳ね上がり、間隔を空ければリアルタイム性が失われる。そこで登場したのがサーバープッシュだ。

SSE(Server-Sent Events)— 一方向ストリーミング

SSE は「一度の接続を維持したまま、サーバーが好きなタイミングでデータを送り続ける」仕組みだ。技術的には HTTPチャンク転送(chunked transfer encoding)がベースで、特別なプロトコルは不要。

ブラウザ側は標準APIの EventSource を使うだけで受信できる。

// クライアント側(受信)
const es = new EventSource('/stream');
es.onmessage = (e) => {
  console.log('受信:', e.data);
};
# サーバー側(FastAPI の例)
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import asyncio

app = FastAPI()

async def event_generator():
    for i in range(10):
        yield f"data: メッセージ {i}\n\n"
        await asyncio.sleep(1)

@app.get("/stream")
async def stream():
    return StreamingResponse(event_generator(), media_type="text/event-stream")

SSEが向いているユースケース:

  • AIチャットの回答ストリーミング(ChatGPT風の表示)
  • 株価・スポーツスコアのリアルタイム表示
  • 通知・アラートの配信
  • ログのライブ表示

WebSocket — 双方向リアルタイム通信

WebSocket はHTTPのハンドシェイクを経てから独自プロトコルに切り替わる、双方向の全二重通信だ。クライアント・サーバー双方から任意のタイミングでメッセージを送れる。

// クライアント側
const ws = new WebSocket('ws://localhost:8000/ws');
ws.onmessage = (e) => console.log('受信:', e.data);
ws.send('こんにちは');
# サーバー側(FastAPI + websockets)
from fastapi import WebSocket

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"エコー: {data}")

WebSocketが向いているユースケース:

  • チャットアプリ(ユーザー同士のリアルタイムやり取り)
  • オンラインゲーム・共同編集ツール
  • ビデオ会議のシグナリング
  • IoTデバイスとの双方向制御

SSE vs WebSocket — 使い分けの基準

観点SSEWebSocket
通信方向サーバー → クライアントのみ双方向
プロトコルHTTP(そのまま)ws:// / wss://
再接続自動(ブラウザ標準)手動実装が必要
実装コスト低いやや高い
ロードバランサ対応比較的容易スティッキーセッション等が必要なことも

「クライアントからも頻繁に送信する必要があるか?」 がシンプルな判断軸だ。サーバーからの一方的な配信ならSSEで十分。双方向のやり取りが必要ならWebSocket。AIアプリのストリーミング表示はSSEで実装されているケースが多い(OpenAI APIのストリーミングもSSEベース)。

まとめ

サーバープッシュ技術の本質は「ブラウザからの定期的な問い合わせをなくし、サーバーが必要なタイミングで届ける」こと。SSEはHTTPの延長線上にあるシンプルな実装で始めやすく、WebSocketは双方向の柔軟性がある。

元記事では「わんこそば(SSE)」「トランシーバー(WebSocket)」という直感的なアナロジーでこの違いを説明している。未経験から転職した筆者が丁寧に書いた入門記事で、コードに入る前にメンタルモデルを整えたい人にとって読みやすい構成になっている。まず概念を掴んでから実装に入りたいなら元記事もあわせて読んでみてほしい。