Vue Academy · レッスン

再接続対応useWebSocket Composable

ComposableによるWebSocketのラップ、指数バックオフでの自動再接続、ステータス追跡

レッスン 4/413 ステップ

「再接続対応useWebSocket Composable」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。

WebSocketをComposableでラップする

コンポーネントごとにWebSocketの生の処理を分散させると、コードが複雑になります。useWebSocket composableに接続状態、再接続、メッセージ処理を集約すれば、どこからでも再利用できます。

これを少しずつ構築していきます。

Refで状態を追跡する

接続状態をリアクティブなstatus refとして公開し、UIに「接続中」、「接続済み」、「切断」のバッジを表示できるようにします。

import { ref } from "vue"

export function useWebSocket(url) {
  const status = ref("CLOSED") // CONNECTING | OPEN | CLOSED
  // ...
  return { status }
}

connect関数

ソケットを開く処理を内部のconnect関数にまとめ、後で再接続するときにもう一度呼び出せるようにします。ライフサイクルイベントごとにstatusを更新します。

let ws
function connect() {
  status.value = "CONNECTING"
  ws = new WebSocket(url)
  ws.onopen = () => { status.value = "OPEN" }
  ws.onclose = () => { status.value = "CLOSED"; scheduleReconnect() }
}

遅延を段階的に増やして再接続する

短いループで即座に再接続を繰り返すと、サーバーに過大な負荷がかかります。指数バックオフを使い、失敗するたびに待ち時間を長くします。ただし、上限を設けます。

let attempts = 0
function scheduleReconnect() {
  attempts++
  const delay = Math.min(1000 * 2 ** attempts, 30000)
  setTimeout(connect, delay)
}

成功時にバックオフをリセットする

接続に成功したら試行回数をリセットしてください。次回切断されたときに、長い遅延からではなく、最初の遅延からバックオフを開始できるようにします。

ws.onopen = () => {
  status.value = "OPEN"
  attempts = 0
  flushQueue()
}

切断中のメッセージキュー

ソケットが停止している間にユーザーが送信しても、メッセージを失わないようにする必要があります。送信メッセージをキューにバッファリングし、接続が開いたらまとめて送信してください。

const queue = []
function send(data) {
  const payload = JSON.stringify(data)
  if (ws && ws.readyState === WebSocket.OPEN) {
    ws.send(payload)
  } else {
    queue.push(payload)
  }
}

キューをフラッシュする

ソケットが開いたら、蓄積されたすべてのメッセージを取り出します。先頭から項目を取り出すことで、順序を維持できます。

function flushQueue() {
  while (queue.length && ws.readyState === WebSocket.OPEN) {
    ws.send(queue.shift())
  }
}

型付きメッセージハンドラー

利用側がメッセージのtypeごとにハンドラーを登録できるようにします。コールバックをマップに保存し、受信した各フレームをメッセージの型に応じて振り分けます。

const handlers = {}
function on(type, cb) { handlers[type] = cb }

// inside connect:
ws.onmessage = (e) => {
  const msg = JSON.parse(e.data)
  if (handlers[msg.type]) handlers[msg.type](msg.payload)
}

onUnmountedでクリーンアップする

composableはタイマーとソケットを管理しています。利用しているコンポーネントがアンマウントされたら、それらを破棄してください。ビューがなくなった後も再接続が実行され続けるのを防ぐためです。

import { onUnmounted } from "vue"

let reconnectTimer
onUnmounted(() => {
  clearTimeout(reconnectTimer)
  if (ws) ws.close(1000, "component unmounted")
})

意図的な切断後の再接続を防ぐ

独自の破棄処理による正常な切断(コード1000)では、再接続を開始してはいけません。intentionalフラグを追跡し、設定されている場合は再接続のスケジュールをスキップします。

let intentional = false
function close() { intentional = true; ws.close(1000) }

ws.onclose = () => {
  status.value = "CLOSED"
  if (!intentional) scheduleReconnect()
}

Composableの全体像

これですべてがまとまりました。作成時に接続し、status、send、onを公開し、切断中はキューに追加し、バックオフを使って再接続し、自動的にクリーンアップします。

export function useWebSocket(url) {
  const status = ref("CLOSED")
  // connect, scheduleReconnect, send, on, flushQueue, cleanup...
  connect()
  return { status, send, on, close }
}

// usage:
// const { status, send, on } = useWebSocket("wss://...")

クイックチェック

再接続戦略について、理解度を確認してください。

まとめ

堅牢なuseWebSocket composableを構築しました。

  • status refでCONNECTING / OPEN / CLOSEDを表し、UIに反映できます。
  • 上限付きの指数バックオフで再接続し、成功時に試行回数をリセットします。
  • 切断中は送信メッセージをキューに追加し、接続が開いたらフラッシュします。
  • 受信したフレームを、メッセージの型ごとに登録したハンドラーコールバックへ振り分けます。
  • onUnmountedでタイマーとソケットをクリーンアップし、意図的な切断後の再接続をスキップします。
無料で開始

AI チューターと学ぶ HTML — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
42
レッスン
156

よくある質問

「再接続対応useWebSocket Composable」レッスンは無料ですか?

はい。「再接続対応useWebSocket Composable」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。

「再接続対応useWebSocket Composable」で何を学びますか?

ComposableによるWebSocketのラップ、指数バックオフでの自動再接続、ステータス追跡 ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Vue Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「再接続対応useWebSocket Composable」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このVue Academyレッスンでコードを書いて実行できますか?

はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ブラウザでのWebSocket入門
  2. VueでのSocket.ioクライアント
  3. リアルタイムチャットコンポーネントの構築
  4. 再接続対応useWebSocket Composable
← Vue Academyに戻る