コンテンツにスキップ

WebSocket 再接続時の重複・欠落・状態不整合をどう防ぐか

問題

ユーザーが10秒インターネット切断し、WebSocket が自動再接続した。重複イベント・欠落メッセージ・クライアント状態の不整合をどう防ぐ?

解決策

1. シーケンス番号 / イベントID

  • 全イベントに一意の連番 or UUID を付与
  • クライアントが最後に処理したイベントIDを保持する

2. 再接続時のリプレイ

クライアント: "lastEventId=42 以降を送って"
サーバー: イベント43, 44, 45... を順に送信

3. 冪等(idempotent)なイベント設計

  • 同じイベントを2回処理しても結果が変わらないように設計
  • クライアント側で処理済みIDを記録し、重複を無視する

4. クライアント状態の再同期

  • 再接続後に全状態をサーバーから取得して上書きする「スナップショット」アプローチ
  • イベントリプレイとスナップショットを組み合わせるのが一般的

ポイント

  • WebSocket は切断を前提に設計する(断線は例外でなく通常の事象)
  • 「at-least-once 配信 + 冪等処理」の組み合わせが鉄板
  • イベントソーシング的な設計と相性が良い