WebSocket은 서버와 클라이언트 간 양방향 실시간 통신을 제공합니다. 채팅, 알림, 실시간 대시보드 등에 필수적인 기술입니다.

면접에서 "실시간 기능을 어떻게 구현하나요?"라고 물으면, WebSocket과 HTTP 폴링의 차이, 재연결 전략까지 설명할 수 있어야 합니다.


WebSocket Composable

TYPESCRIPT
// composables/useWebSocket.ts
import { ref, onMounted, onUnmounted } from 'vue'

interface UseWebSocketOptions {
  autoReconnect?: boolean
  reconnectInterval?: number
  maxRetries?: number
}

export function useWebSocket(url: string, options: UseWebSocketOptions = {}) {
  const { autoReconnect = true, reconnectInterval = 3000, maxRetries = 5 } = options

  const data = ref<any>(null)
  const status = ref<'CONNECTING' | 'OPEN' | 'CLOSING' | 'CLOSED'>('CLOSED')
  const error = ref<Event | null>(null)

  let ws: WebSocket | null = null
  let retryCount = 0

  const connect = () => {
    ws = new WebSocket(url)
    status.value = 'CONNECTING'

    ws.onopen = () => {
      status.value = 'OPEN'
      retryCount = 0
    }

    ws.onmessage = (event) => {
      data.value = JSON.parse(event.data)
    }

    ws.onerror = (e) => {
      error.value = e
    }

    ws.onclose = () => {
      status.value = 'CLOSED'
      if (autoReconnect && retryCount < maxRetries) {
        retryCount++
        setTimeout(connect, reconnectInterval)
      }
    }
  }

  const send = (message: any) => {
    if (ws?.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify(message))
    }
  }

  const close = () => {
    retryCount = maxRetries  // 재연결 방지
    ws?.close()
  }

  onMounted(connect)
  onUnmounted(close)

  return { data, status, error, send, close }
}
VUE
<script setup lang="ts">
import { useWebSocket } from '@/composables/useWebSocket'
import { watch } from 'vue'

const { data, status, send } = useWebSocket('wss://api.example.com/ws')

// 메시지 수신 감시
watch(data, (message) => {
  if (message) {
    console.log('수신:', message)
  }
})

const sendMessage = (text: string) => {
  send({ type: 'chat', text })
}
</script>

<template>
  <div>
    <p>상태: {{ status }}</p>
    <p>최근 메시지: {{ data }}</p>
    <button @click="sendMessage('안녕!')">메시지 전송</button>
  </div>
</template>

Socket.IO와 Vue

TYPESCRIPT
// composables/useSocket.ts
import { ref, onMounted, onUnmounted } from 'vue'
import { io, Socket } from 'socket.io-client'

export function useSocket(url: string) {
  const isConnected = ref(false)
  let socket: Socket

  const connect = () => {
    socket = io(url, {
      reconnection: true,
      reconnectionAttempts: 5,
      reconnectionDelay: 1000
    })

    socket.on('connect', () => { isConnected.value = true })
    socket.on('disconnect', () => { isConnected.value = false })
  }

  const on = (event: string, handler: (...args: any[]) => void) => {
    socket.on(event, handler)
  }

  const emit = (event: string, ...args: any[]) => {
    socket.emit(event, ...args)
  }

  onMounted(connect)
  onUnmounted(() => { socket?.disconnect() })

  return { isConnected, on, emit }
}

WebSocket vs 대안 기술

기술방향연결적합한 경우
WebSocket양방향지속채팅, 게임, 실시간 협업
SSE서버→클라이언트지속알림, 실시간 피드
Long Polling양방향(느림)반복 요청레거시 호환

면접 팁

  • WebSocket의 **핸드셰이크 과정 **(HTTP Upgrade)을 설명할 수 있으면 좋습니다
  • 재연결 전략에서 ** 지수 백오프(Exponential Backoff)**를 적용하는 이유를 설명하세요
  • 대규모 실시간 시스템에서의 ** 채널/룸 패턴 **을 알고 있으면 아키텍처 이해도를 보여줄 수 있습니다

요약

Vue에서 WebSocket은 composable로 캡슐화하여 연결 관리, 메시지 송수신, 자동 재연결을 처리합니다. Socket.IO는 폴백 메커니즘과 룸/네임스페이스 기능으로 실전에서 자주 사용됩니다. 데이터 흐름 방향에 따라 WebSocket, SSE, 폴링 중 적절한 기술을 선택합니다.

댓글 로딩 중...