Post

WebSocket - 실시간 통신을 위한 프로토콜

WebSocket - 실시간 통신을 위한 프로토콜

1. WebSocket이란?

WebSocket은 클라이언트와 서버 간의 양방향, 지속적 연결을 지원하는 프로토콜이다.

HTTP 요청-응답 방식과 달리 WebSocket은 연결이 한 번 성립되면 서버와 클라이언트가 실시간으로 데이터를 주고받을 수 있는 통신 채널을 유지한다.

주로 채팅, 실시간 알림, 스트리밍 서비스 등 실시간성이 중요한 애플리케이션에서 활용된다.


2. WebSocket의 특징

  1. 양방향 통신
    • 클라이언트와 서버가 서로 데이터를 동시에 주고받을 수 있다.
  2. 상태 유지
    • 연결이 열려 있는 동안, 상태를 유지하며 추가적인 핸드셰이크가 필요 없다.
  3. 효율성
    • 데이터 전송 시 헤더 오버헤드가 적어 HTTP보다 효율적이다.
  4. 이벤트 기반 통신
    • 서버에서 클라이언트로 데이터를 즉시 푸시(push)할 수 있다.

3. WebSocket 동작 원리

  1. 핸드셰이크
    • 클라이언트가 HTTP를 통해 서버에 WebSocket 연결 요청을 보낸다.
    • 서버가 요청을 승인하면 WebSocket 프로토콜로 업그레이드된다.
  2. 지속적 연결
    • 연결이 성립되면 클라이언트와 서버는 지속적으로 데이터를 주고받는다.
  3. 종료
    • 연결은 클라이언트나 서버가 명시적으로 종료하거나, 네트워크 문제가 발생했을 때 종료된다.

4. WebSocket API

WebSocket은 브라우저에서 네이티브 API를 통해 쉽게 사용할 수 있다.

4.1 기본 사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// WebSocket 연결 생성
const socket = new WebSocket("ws://localhost:3000");

// 연결이 열렸을 때
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);
};

5. Next.js와 WebSocket

5.1 WebSocket 서버 설정

Next.js에서는 API Routes를 사용해 WebSocket 서버를 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// pages/api/socket.js
import { Server } from "ws";

export default function handler(req, res) {
  if (res.socket.server.wss) {
    console.log("WebSocket 서버가 이미 실행 중");
    res.end();
    return;
  }

  const wss = new Server({ server: res.socket.server });
  res.socket.server.wss = wss;

  wss.on("connection", (ws) => {
    console.log("클라이언트 연결됨");

    ws.on("message", (message) => {
      console.log("받은 메시지:", message);
      ws.send(`서버 응답: ${message}`);
    });

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

  console.log("WebSocket 서버 실행 완료");
  res.end();
}

5.2 클라이언트 WebSocket 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// app/page.js
"use client";

import { useEffect } from "react";

export default function HomePage() {
  useEffect(() => {
    const socket = new WebSocket("ws://localhost:3000/api/socket");

    socket.onopen = () => {
      console.log("WebSocket 연결 열림");
      socket.send("안녕하세요 서버!");
    };

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

    socket.onclose = () => {
      console.log("WebSocket 연결 닫힘");
    };

    return () => {
      socket.close();
    };
  }, []);

  return <h1>WebSocket 테스트</h1>;
}

7. WebSocket vs. HTTP

특징WebSocketHTTP
연결 방식지속적 연결요청-응답 기반
양방향 통신가능불가능
데이터 전송 속도빠름 (헤더 오버헤드 적음)비교적 느림 (매 요청마다 헤더 포함)
사용 사례채팅, 알림, 게임, 스트리밍일반 웹 브라우징, API 호출

8. WebSocket 사용 사례

  1. 채팅 애플리케이션
    • 실시간 메시지 전송 및 수신.
  2. 실시간 알림 시스템
    • 푸시 알림을 서버에서 클라이언트로 전송.
  3. 멀티플레이어 게임
    • 플레이어 간의 실시간 상태 동기화.
  4. 주식/암호화폐 시세 업데이트
    • 초 단위로 변경되는 데이터를 실시간으로 표시.
  5. IoT 장치 통신
    • 디바이스 상태를 실시간으로 모니터링.

9. WebSocket의 한계와 대안

  1. 브라우저 호환성
    • 대부분의 최신 브라우저에서 지원되지만, 구형 브라우저에서는 사용할 수 없다.
  2. HTTP/2의 등장
    • HTTP/2는 서버 푸시 기능을 제공하여 WebSocket의 일부 사용 사례를 대체 가능하다.
  3. 대안 기술
    • WebSocket이 적합하지 않은 경우, SSE(Server-Sent Events) 또는 Polling을 사용할 수 있다.

10. 정리

WebSocket은 실시간 통신이 필요한 애플리케이션에서 필수적인 기술이다.

Next.js와 Node.js를 활용하면 WebSocket 서버를 간단히 구축하고 클라이언트와 실시간으로 데이터를 주고받을 수 있다.

효율적인 데이터 전송, 양방향 통신, 지속적 연결과 같은 특성을 활용해 사용자 경험을 크게 개선할 수 있다.

This post is licensed under CC BY 4.0 by the author.