WebSocket 실시간 통신
WebSocket은 서버와 클라이언트 간 양방향 실시간 통신을 제공합니다. 채팅, 알림, 실시간 대시보드 등에 필수적인 기술입니다.
면접에서 "실시간 기능을 어떻게 구현하나요?"라고 물으면, WebSocket과 HTTP 폴링의 차이, 재연결 전략까지 설명할 수 있어야 합니다.
WebSocket Composable
// 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 }
}
<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
// 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, 폴링 중 적절한 기술을 선택합니다.
댓글 로딩 중...