WebSocket

handa·2025년 7월 3일
0
post-thumbnail

WebSocket은 클라이언트(주로 브라우저)와 서버 간에 지속적이고 양방향(Full-duplex) 통신을 제공하는 네트워크 프로토콜입니다.
HTTP의 요청-응답 모델과 달리, 한 번 연결이 성립되면 양쪽에서 자유롭게 데이터를 주고받을 수 있어 실시간성이 중요한 다양한 서비스(채팅, 알림, 게임, 주식 시세 등)에 널리 사용됩니다.

WebSocket의 동작 원리

  1. 핸드셰이크(Handshake)
  • 클라이언트가 HTTP 프로토콜로 서버에 WebSocket 연결을 요청합니다.

  • 서버가 이를 수락하면, HTTP 프로토콜에서 WebSocket 프로토콜로 업그레이드(Upgrade)됩니다.

  1. 지속적 연결(Persistent Connection)
  • 연결이 성립된 후에는 TCP 연결이 계속 열려 있어, 클라이언트와 서버가 언제든 데이터를 주고받을 수 있습니다.
  1. 메시지 전송
  • 양방향으로 텍스트/바이너리 데이터를 프레임 단위로 주고받습니다.

  • 서버가 먼저 클라이언트로 메시지를 push할 수도 있습니다.

  1. 연결 종료
  • 어느 한 쪽에서 close 프레임을 보내면 연결이 종료됩니다.

WebSocket의 특징

  • Full-duplex, Low-latency
    양방향, 저지연 통신(HTTP Polling, SSE 대비 오버헤드가 적음)

  • 단일 연결
    한 번 연결 후, 다수의 메시지를 주고받으며 추가 연결/해제 과정이 없음

  • 실시간성
    서버에서 클라이언트로 즉시 데이터 전송 가능(예: 알림, 실시간 채팅 등)

  • 표준 포트 사용
    ws://(80), wss://(443) 포트를 사용해 방화벽 환경에서도 활용 가능

  • 브라우저 지원
    Chrome, Firefox, Edge, Safari 등 대부분의 최신 브라우저에서 기본 지원

WebSocket의 주요 활용 사례

분야예시 및 설명
실시간 채팅메신저, 라이브 방송 채팅, 고객센터 채팅 등
데이터 방송실시간 주식/코인 시세, 스포츠 점수, 뉴스 속보
동기화/협업Figma, Google Docs 등 실시간 공동 편집
게임/IoT멀티플레이어 게임, IoT 기기 상태 모니터링
알림/푸시실시간 알림, 상태 변화 알림 등
  • 대표 서비스: Facebook Messenger, Discord, Slack, WhatsApp Web, YouTube Live, Airbnb, Uber, Netflix, Twitch, GitHub, Figma 등

WebSocket API (JavaScript 예시)

const socket = new WebSocket('wss://example.com/socket');

socket.onopen = () => {
  console.log('WebSocket 연결 완료');
  socket.send('Hello Server!');
};

socket.onmessage = (event) => {
  console.log('서버로부터 메시지:', event.data);
};

socket.onclose = () => {
  console.log('WebSocket 연결 종료');
};

socket.onerror = (error) => {
  console.error('WebSocket 에러:', error);
};
  • ws://는 비암호화, wss://는 암호화된 연결에 사용됩니다.

Spring Boot에서 WebSocket 서버 구현

1. 의존성 추가

Gradle

implementation 'org.springframework.boot:spring-boot-starter-websocket'

Maven

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2. WebSocket 설정 클래스

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic"); // 구독 경로
        config.setApplicationDestinationPrefixes("/app"); // 메시지 송신 경로
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws-chat").setAllowedOrigins("*").withSockJS(); // 엔드포인트 등록
    }
}
  • @EnableWebSocketMessageBroker로 STOMP 기반 메시지 브로커 활성화

  • SockJS 지원으로 WebSocket 미지원 환경에서도 fallback 가능

3. 메시지 모델 및 컨트롤러

Message 모델

public class ChatMessage {
    private String from;
    private String text;
    // getter, setter
}

메시지 처리 컨트롤러

@Controller
public class ChatController {
    @MessageMapping("/chat")
    @SendTo("/topic/messages")
    public ChatMessage send(ChatMessage message) {
        return message;
    }
}
  • /app/chat으로 메시지 전송 시, /topic/messages를 구독한 모든 클라이언트에게 전달

4. 클라이언트(브라우저) 예시

<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs@2/dist/stomp.min.js"></script>
<script>
  var socket = new SockJS('/ws-chat');
  var stompClient = Stomp.over(socket);
  stompClient.connect({}, function(frame) {
    stompClient.subscribe('/topic/messages', function(message) {
      console.log('수신:', JSON.parse(message.body));
    });
    stompClient.send("/app/chat", {}, JSON.stringify({from: "user", text: "안녕하세요!"}));
  });
</script>
  • SockJS와 STOMP를 활용해 다양한 브라우저와 네트워크 환경을 지원

WebSocket 사용시 Best Practices

  • 보안: 항상 wss://(TLS) 프로토콜 사용 권장

  • 하트비트(Heartbeat): 주기적 ping/pong 메시지로 연결 유지

  • 에러 핸들링: 연결 실패/종료/재연결 처리 로직 구현

  • 연결 제한: 서버 리소스 보호를 위해 동시 연결 수 제한

HTTP vs WebSocket

출저: https://blog.scaleway.com/iot-hub-what-use-case-for-websockets
구분HTTPWebSocket
통신 방향단방향 (클라이언트 → 서버)양방향 (클라이언트 ↔ 서버, Full-duplex)
연결 방식요청-응답 후 연결 종료, 매 요청마다 새 연결한 번 연결 후 지속적으로 연결 유지
오버헤드높음 (매 요청마다 헤더 포함, 연결/해제 반복)낮음 (초기 핸드셰이크 후 작은 프레임만 사용)
실시간성낮음 (폴링, 롱폴링 필요)매우 높음 (즉시 데이터 송수신 가능)
상태 관리무상태 (Stateless)상태 유지 (Stateful, 연결 지속)
주요 활용 사례웹페이지, API, 파일 다운로드, 정적 데이터채팅, 알림, 게임, 실시간 데이터 방송 등
데이터 형식주로 텍스트 (HTML, JSON, XML)텍스트/바이너리 모두 지원
보안 프로토콜HTTPS (443)WSS (443)
profile
진짜 해보자

0개의 댓글