0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ポーリング・ロングポーリング・WebSocketの違いを実装で理解する

Posted at

はじめに

リアルタイムっぽい処理を実装しようとすると、必ず出てくるこの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」ではなく
要件に対して十分かどうか

で選ぶことです。

この記事が、
通信方式を選ぶときの判断材料になれば幸いです 🙌

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?