Vue Academy · 강의

재연결 기능이 있는 useWebSocket 컴포저블

WebSocket을 컴포저블로 감싸고, 지수 백오프를 적용한 자동 재연결과 상태 추적을 구현합니다.

레슨 4/413개 단계

재연결 기능이 있는 useWebSocket 컴포저블은(는) CoddyKit의 무료 Vue Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Vue Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Vue Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

WebSockets를 컴포저블로 감싸기

컴포넌트 곳곳에 원시 WebSocket 처리를 흩어 놓으면 코드가 복잡해집니다. useWebSocket 컴포저블은 연결 상태, 재연결, 메시지 처리를 한곳에 모아 주므로 어디서든 재사용할 수 있습니다.

이제 이를 한 단계씩 만들어 보겠습니다.

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)
  }
}

대기열 비우기

소켓이 열리면 쌓여 있던 모든 항목을 처리하세요. 순서를 유지하려면 앞에서부터 항목을 shift하세요.

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에서 정리하기

이 컴포저블은 타이머와 소켓을 관리합니다. 사용하는 컴포넌트가 마운트 해제될 때 이를 정리하여 뷰가 사라진 후에도 재연결이 계속 실행되지 않도록 하세요.

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()
}

컴포저블 전체 구성

이제 모든 요소가 하나로 연결됩니다. 생성 시 연결하고, 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 컴포저블을 만들었습니다.

  • status ref는 UI에 표시할 CONNECTING / OPEN / CLOSED 상태를 반영합니다.
  • 지수 백오프로 재연결하고 최대 지연 시간을 제한하며, 성공하면 카운터를 초기화합니다.
  • 연결이 끊긴 동안 발신 메시지를 대기열에 저장하고 연결이 열리면 처리합니다.
  • 들어오는 프레임을 유형별 핸들러 콜백으로 전달합니다.
  • onUnmounted에서 타이머와 소켓을 정리하고, 의도적인 종료 후에는 재연결을 건너뜁니다.
무료로 시작

AI 튜터와 함께 HTML을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
42
레슨
156

자주 묻는 질문

“재연결 기능이 있는 useWebSocket 컴포저블” 강의는 무료인가요?

네 — “재연결 기능이 있는 useWebSocket 컴포저블” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Vue Academy 강의 전체를 잠금 해제할 수 있습니다. Vue Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“재연결 기능이 있는 useWebSocket 컴포저블”에서 뭘 배우나요?

WebSocket을 컴포저블로 감싸고, 지수 백오프를 적용한 자동 재연결과 상태 추적을 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Vue Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Vue Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Vue Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“재연결 기능이 있는 useWebSocket 컴포저블” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Vue Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Vue Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 브라우저에서 WebSocket 기초 다지기
  2. Vue에서 Socket.io 클라이언트 사용
  3. 실시간 채팅 컴포넌트 만들기
  4. 재연결 기능이 있는 useWebSocket 컴포저블
← Vue Academy(으)로 돌아가기