Spring

WebSocket

NellKiM 2024. 12. 5. 09:46

WebSocketHTML5에서 제공하는 양방향 통신 프로토콜 클라이언트와 서버 간에 **지속적인 연결(persistent connection)**을 유지하면서, 양방향으로 데이터를 실시간으로 주고받을 수 있도록 설계되었습니다. WebSocket은 HTTP와 함께 사용되지만, HTTP와는 다른 독립적인 프로토콜

주요 특징

  1. 양방향 통신 (Full-Duplex):
    • 클라이언트와 서버가 서로 동시에 데이터를 주고받을 수 있습니다.
    • 요청-응답 패턴이 아니라, 필요할 때 자유롭게 메시지를 주고받음.
  2. 지속적인 연결 유지:
    • 클라이언트와 서버가 연결을 맺은 이후에는 지속적으로 연결을 유지합니다.
    • 새로 요청을 보내거나 연결을 다시 설정하지 않아도 실시간 데이터를 주고받을 수 있습니다.
  3. 낮은 오버헤드:
    • HTTP는 요청마다 헤더를 전송해야 하지만, WebSocket은 초기 핸드셰이크 이후 추가적인 헤더 없이 데이터를 주고받습니다.
    • 이를 통해 대역폭 절약지연 시간 감소가 가능합니다.
  4. 이벤트 기반 통신:
    • 데이터가 발생할 때마다 실시간으로 전달 가능.
    • 특히 채팅 애플리케이션, 실시간 알림, 주식 데이터와 같은 실시간성이 중요한 애플리케이션에서 유용합니다.

동작 원리

  1. 핸드셰이크(Handshake):
    • WebSocket은 처음에는 HTTP 프로토콜을 사용하여 연결을 시작합니다.
    • 클라이언트가 서버에 WebSocket 연결을 요청하며, 서버가 이를 승인하면 WebSocket 연결이 성립됩니다.
      1. 지속적인 데이터 통신:
        • 핸드셰이크 이후에는 WebSocket 프로토콜로 전환되어 양방향 데이터 통신이 이루어집니다.
        • 데이터는 프레임(Frame) 단위로 주고받습니다.
      2. 연결 종료:
        • 클라이언트나 서버 중 하나가 명시적으로 연결을 종료하거나 네트워크 문제로 연결이 끊어질 수 있습니다.
    • WebSocket의 구조
      • Opcode: 메시지 타입 (텍스트, 바이너리 등)
      • Payload Length: 메시지 길이
      • Masking Key: 데이터를 암호화하기 위한 키 (클라이언트->서버 데이터에만 적용)
      • Payload Data: 실제 데이터
    • WebSocket 메시지는 다음과 같은 구조로 프레임화됩니다:
    • WebSocket과 HTTP의 비교특징HTTPWebSocket
      통신 방식 요청-응답 (Request-Response) 양방향 (Full-Duplex)
      연결 방식 요청마다 새 연결 연결을 유지 (Persistent Connection)
      오버헤드 요청마다 헤더를 포함 초기 핸드셰이크 이후 헤더 없음
      실시간성 낮음 (폴링 또는 롱 폴링 필요) 높음
      주요 활용 사례 정적인 웹 페이지, API 실시간 채팅, 게임, 알림, IoT 데이터 스트리밍
      WebSocket의 주요 활용 사례
      1. 실시간 채팅:
        • 예: Slack, WhatsApp Web, Discord
      2. 실시간 알림 시스템:
        • 예: 이메일 알림, 쇼핑몰의 실시간 주문 상태 업데이트
      3. 온라인 게임:
        • 실시간 멀티플레이어 게임에서 유용
      4. 금융 데이터 스트리밍:
        • 주식 시장 데이터, 환율 정보 등
      5. IoT(사물 인터넷):
        • 장치 간 실시간 데이터 교환
      6. 화상 회의 및 스트리밍:
        • 예: WebRTC와의 통합
// WebSocket 서버에 연결
const socket = new WebSocket('ws://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);
};
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });

server.on('connection', (socket) => {
    console.log('클라이언트 연결됨');

    // 클라이언트로부터 메시지 수신
    socket.on('message', (message) => {
        console.log('클라이언트 메시지:', message);
        socket.send('Hello, Client!');
    });

    // 연결 종료
    socket.on('close', () => {
        console.log('클라이언트 연결 종료');
    });
});

console.log('WebSocket 서버가 8080 포트에서 실행 중');

WebSocket의 장단점

장점

  • 실시간 데이터 전송에 적합.
  • 낮은 오버헤드로 효율적 데이터 전송.
  • 서버 푸시(push) 기능 지원.
  • 요청-응답 구조보다 빠른 반응성.

단점

  • 네트워크 환경이 안정적이지 않은 경우 성능 저하.
  • 클라이언트와 서버 간 연결 상태를 관리해야 함.
  • HTTP보다 구현이 복잡.