Skip to content

websocket protocol

김동완 edited this page Feb 1, 2026 · 1 revision

2. 웹소켓 연결 규약

1. 연결 host

WebSocket은 최초 연결 시 HTTP 기반 핸드셰이크를 수행합니다.

따라서 시그널링 서버와 WebSocket 연결을 맺기 위해서는 HTTP URL(host) 이 필요합니다.

일반적인 WebSocket 구현에서는 직접 쿼리를 구성해야 하지만,

본 시스템은 socket.io를 사용하므로 보다 간단하게 연결할 수 있습니다.

아래는 프론트엔드가 시그널링 서버와 WebSocket 연결을 맺을 때 사용하는 기본 코드입니다.

import { io } from "socket.io-client";

const socket = io(`${backend_url}/signal`, {
  path: "/api/ws",              // WEBSOCKET_PATH
  transports: ["websocket"],    // 서버가 websocket only
});

2. WebSocket 연결의 3요소

WebSocket 연결에는 다음 3가지 요소가 반드시 필요합니다.

2-1. Base URL

  • 코드에서 ${backend_url} 에 해당합니다.

  • REST API 호출 시에는

    http://localhost:8080/api 를 사용했지만,

  • WebSocket 연결 시에는 실제 호스트 주소

    http://localhost:8080 을 사용해야 합니다.

예시 (로컬 환경):

import { io } from "socket.io-client";

const socket = io("http://localhost:8080/signal", {
  path: "/api/ws",              // WEBSOCKET_PATH
  transports: ["websocket"],    // 서버가 websocket only
});

📌 권장 사항

  • 테스트 서버 / 운영 서버가 다르므로
  • backend_url 은 반드시 환경변수로 관리하는 것을 권장합니다.
  • 해당 값만 공유해주시면 CI/CD 반영에는 문제가 없습니다.

2-2. path

  • pathSocket.IO 핸드셰이크가 붙는 HTTP 경로입니다.
  • 실제 요청은 내부적으로 다음과 같은 형태로 전송됩니다.
http://localhost:8080/{path}/?EIO=4&transport=websocket
  • 테스트 서버에서는 이 path필수 요소이며,
  • 해당 값이 일치하지 않으면 WebSocket 연결이 실패합니다.
path: "/api/ws"

2-3. Namespace

  • 본 시스템의 시그널링 WebSocket namespace는 다음과 같습니다.
/signal
  • namespace는 같은 WebSocket 서버 내에서 논리적으로 연결을 분리하기 위한 개념입니다.
  • 모든 시그널링 관련 통신은 /signal namespace를 통해 이루어집니다.
io("http://localhost:8080/signal", { ... });

3. WebSocket 사용 규약

3-1. Socket 객체 관리

프론트엔드는 생성된 socket 객체를 useRef, 전역 상태, 싱글톤 등 연결이 유지되는 방식으로 관리해야 합니다.

3-2. 기본 연결 이벤트 처리

아래 이벤트들은 프론트엔드에서 반드시 처리할 것을 권장합니다.

socket.on("connect", () => {
  // 연결 완료
});

socket.on("disconnect", (reason) => {
  // 서버 disconnect(true)로 끊길 수 있음
  // 보통 방에 인원이 가득 차거나 연결이 불안정할때 생길 수 있습니다. 
});

socket.on("connect_error", (err) => {
	// 무슨 에러가 발생한 것입니다. 이를 헨드링 할 수 있습니다.
});
  • connect

    → WebSocket 연결이 정상적으로 완료된 상태

    → 이 시점부터 시그널링 이벤트 송수신 가능

  • disconnect

    → 서버 정책에 의해 강제로 끊길 수 있음

    reason 을 기반으로 사용자 알림 처리 가능

  • connect_error

    → 인증 실패, 네트워크 오류 등

    → 재시도 또는 에러 UI 처리 가능

3-3. 인증 관련 이벤트 (auth:access_token)

회원으로 접속한 경우,

WebSocket

핸드셰이크 과정에서 refresh_token으로 인해 access_token이 갱신되었을 때만

아래 이벤트가 서버 → 클라이언트로 전달됩니다.

socket.on("auth:access_token", ({ access_token }) => {
  // access_token이 갱신된 경우에만 전달됨
});
  • 해당 이벤트는 항상 오는 것이 아닙니다
  • 전달된다는 것은 access_token이 새로 발급되었음을 의미합니다.

3-4. 회원 접속 시 주의 사항

회원 접속의 경우,

HTTP 핸드셰이크 단계에서 인증 정보를 함께 전달해야 합니다.

import { io } from "socket.io-client";

const socket = io("http://localhost:8080/signal", {
  path: "/api/ws",
  transports: ["websocket"],
  withCredentials: true,        // 쿠키 기반 인증 사용 시 필수
  headers: {
    Authorization: "Bearer <access_token>",
  },
});
  • 비회원(게스트) 접속의 경우

    headers, withCredentials 를 설정하면 의도적으로 에러가 발생하도록 설계되어 있습니다.

  • 인증 관련 설정은 회원 접속 시에만 적용해야 합니다.

Clone this wiki locally