T_era

실시간 데이터 전송 방식 정리 본문

Programing/Spring

실시간 데이터 전송 방식 정리

블스뜸 2025. 7. 1. 16:59

1. 데이터 전송 방식의 종류

  • 브로드캐스트(Broadcast)
    네트워크에 연결된 모든 디바이스(클라이언트)에게 데이터를 전송하는 방식
  • 유니캐스트(Unicast)
    한 명의 특정 클라이언트에게만 데이터를 전송
  • 멀티캐스트(Multicast)
    여러 명의 특정 그룹(여러 클라이언트)에게만 데이터를 전송

2. 옛날 방식: Polling

  • Polling
    클라이언트가 주기적으로 서버에 데이터를 요청하는 방식
  • Short-Polling
    • 일정 주기마다 서버에 요청
    • 구현이 쉽지만, 불필요한 네트워크 트래픽 발생
  • Long-Polling
    • 클라이언트가 요청 후, 서버에서 데이터가 준비될 때까지 대기
    • 데이터가 준비되면 응답, 아니면 타임아웃
    • Short-Polling보다 오버헤드가 적음

3. Server-Sent Events (SSE)

  • 특징
    • 서버 → 클라이언트 단방향 실시간 데이터 전송
    • HTTP 기반 (Content-Type: text/event-stream)
    • 브라우저가 자동으로 재연결 시도
  • 단점
    • 단방향(서버→클라이언트)만 지원
    • 브라우저 호환성 이슈(IE 미지원)
    • 클라이언트 연결 종료 감지 어려움

간단 예시 (Kotlin/Spring):

@RestController
class SseController {
    @GetMapping("/sse", produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
    fun sseEmitter(): SseEmitter {
        return SseEmitter().apply {
            send("안녕하세요! 현재 시간: ${LocalDateTime.now()}")
            complete()
        }
    }
}

4. WebSocket

  • 특징
    • 서버 ↔ 클라이언트 양방향 실시간 통신(Full-Duplex)
    • 저지연, 낮은 오버헤드
  • 단점
    • 세션 관리 및 Scale-Out이 어려움
    • 재연결 로직 직접 구현 필요

핵심 코드 예시 (Kotlin/Spring):

@Configuration
@EnableWebSocket
class WebSocketConfig : WebSocketConfigurer {
    override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
        registry.addHandler(ChatWebSocketHandler(), "/chat").setAllowedOrigins("*")
    }
}

@Component
class ChatWebSocketHandler : TextWebSocketHandler() {
    private val sessions = mutableSetOf<WebSocketSession>()
    override fun afterConnectionEstablished(session: WebSocketSession) { sessions.add(session) }
    override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
        sessions.forEach { it.sendMessage(TextMessage("에코: ${message.payload}")) }
    }
    override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) { sessions.remove(session) }
}

동작 과정

  1. 클라이언트가 HTTP 요청에 Upgrade: websocket 헤더를 추가해 프로토콜 업그레이드 요청
  2. 서버가 101 Switching Protocols로 응답, WebSocket 연결 성립
  3. 이후 데이터는 Frame 단위로 양방향 송수신

5. STOMP (Simple Text Oriented Messaging Protocol)

  • 특징
    • WebSocket 위에서 동작하는 메시징 프로토콜
    • 목적지(토픽) 기반 메시지 송수신
    • 외부 브로커(RabbitMQ, ActiveMQ 등) 연동 가능

핵심 코드 예시 (Kotlin/Spring):

@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
        registry.addEndpoint("/ws")
    }
    override fun configureMessageBroker(registry: MessageBrokerRegistry) {
        registry.setApplicationDestinationPrefixes("/app")
        registry.enableSimpleBroker("/topic")
    }
}

@Controller
class GreetingController {
    @MessageMapping("/greeting")
    fun handle(greeting: String): String = "[${getTimestamp()}] $greeting"
    private fun getTimestamp() = SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(Date())
}
  • 클라이언트가 /topic/greeting을 구독하면, /app/greeting으로 메시지 전송 시 브로커가 구독자에게 전달

6. 요약

방식 특징 장점 단점
Polling 주기적 요청 구현 쉬움 불필요 트래픽
Long-Polling 서버에서 대기 후 응답 오버헤드 적음 구현 복잡
SSE 서버→클라이언트 단방향 표준, 간단 단방향, IE 미지원
WebSocket 양방향, Full-Duplex 실시간, 저지연 세션/스케일 관리 어려움
STOMP 토픽 기반 메시징(WebSocket) 브로커 연동 쉬움 브로커 필요