はじめに
リアルタイムっぽい処理を実装しようとすると、必ず出てくるこの3つ。
- ポーリング
- ロングポーリング
- WebSocket
名前は聞いたことがあるけど、
- 何がどう違うのか
- どこで使い分けるのか
- 実装すると何が変わるのか
が ふわっとした理解のまま になりがちです。
この記事では、
- 考え方の違い
- 通信の流れ
- 最小限の実装例
を並べて、体感的に違いが分かる ことを目指します。
まず結論:何が違うのか
最初にざっくり整理します。
| 方式 | 通信の特徴 | サーバーからの通知 |
|---|---|---|
| ポーリング | 定期的に問い合わせ | できない |
| ロングポーリング | レスポンスを遅らせる | 疑似的にできる |
| WebSocket | 常時接続 | できる |
違いは 「接続を維持するかどうか」 です。
ポーリング(Polling)
考え方
「変わった?」って定期的に聞きに行く
一定間隔でサーバーにリクエストを送り、
毎回最新状態を取得します。
通信イメージ
Client → Server : 変わった?
Server → Client : まだ
(数秒後)
Client → Server : 変わった?
実装例(JavaScript + Fetch)
setInterval(async () => {
const res = await fetch("/api/status");
const data = await res.json();
console.log(data);
}, 5000);
実行ログ
[12:00:00] GET /api/status
[12:00:05] GET /api/status
[12:00:10] GET /api/status
[12:00:15] GET /api/status
特徴
- 実装がとても簡単
- 無駄なリクエストが多い
- リアルタイム性は低い
ロングポーリング(Long Polling)
考え方
「変わるまで待ってていいから、変わったら教えて」
サーバー側が すぐにレスポンスを返さず、
データが更新されるまで接続を保持します。
通信イメージ
Client → Server : 変わった?
(しばらく待つ)
Server → Client : 変わったよ
Client → Server : 次も待つ
実装例(Express)
サーバー側
let listeners = [];
app.get("/api/long-poll", (req, res) => {
listeners.push(res);
});
function notify(data) {
listeners.forEach(res => res.json(data));
listeners = [];
}
クライアント側
async function poll() {
const res = await fetch("/api/long-poll");
const data = await res.json();
console.log(data);
poll(); // 次の待機
}
poll();
実行ログ
[12:00:00] GET /api/long-poll (waiting...)
[12:00:08] respond 200
[12:00:08] GET /api/long-poll (waiting...)
特徴
- 疑似的にリアルタイム
- HTTPのまま実現できる
- 同時接続が増えるとサーバー負荷が高い
WebSocket
考え方
「最初につないで、あとはいつでも話そう」
最初に接続を確立し、
その後は 双方向で自由に通信 します。
通信イメージ
Client ⇄ Server (常時接続)
実装例(WebSocket)
サーバー側(Node.js)
import { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", ws => {
ws.send("connected");
setInterval(() => {
ws.send(JSON.stringify({ message: "update" }));
}, 3000);
});
クライアント側
const ws = new WebSocket("ws://localhost:8080");
ws.onmessage = event => {
console.log(event.data);
};
実行ログ
[12:00:00] WebSocket connected
[12:00:03] send message
[12:00:06] send message
[12:00:09] send message
特徴
- 完全なリアルタイム通信
- 無駄なリクエストがない
- 実装・運用はやや複雑
どう使い分けるか
| 要件 | おすすめ |
|---|---|
| とりあえず状態確認 | ポーリング |
| 擬似リアルタイム | ロングポーリング |
| チャット・通知 | WebSocket |
まとめ
-
ポーリング
- 定期的に聞きに行く
- シンプルだが非効率
-
ロングポーリング
- HTTPでリアルタイム風
- スケールに注意
-
WebSocket
- 常時接続の双方向通信
- 本格リアルタイム向け
重要なのは、
「リアルタイムだからWebSocket」ではなく
要件に対して十分かどうか
で選ぶことです。
この記事が、
通信方式を選ぶときの判断材料になれば幸いです 🙌