[Node.js] WebSocket

Main·2024년 10월 7일
0

Node.js

목록 보기
16/20
post-thumbnail

WebSoket ?

WebSocket은 TCP 소켓 연결을 통해 클라이언트와 서버 간의 양방향 통신을 가능하게 합니다. 일반적인 HTTP 통신에서는 클라이언트가 요청을 보내고 서버가 응답을 반환하는 방식으로 동작합니다. 반면 WebSocket은 클라이언트가 연결을 초기화한 후 지속적으로 열린 연결을 유지하며 양측이 데이터를 자유롭게 보낼 수 있습니다.

최신 브라우저는 대부분 웹 소켓을 지원하며, 노드는 wsSocket.IO 같은 패키지를 통해 웹 소켓 사용 가능합니다.


WebSokect의 동작원리

1 ) 연결 초기화 (Handshake)

WebSocket 통신은 처음에 HTTP 요청을 통해 시작됩니다. 이 과정은 "핸드셰이크"라고 불립니다. 클라이언트는 서버에 WebSocket 연결을 요청하는데, 이 과정은 다음과 같습니다.

클라이언트의 업그레이드 요청

  • 클라이언트는 서버에 Upgrade 헤더가 포함된 특별한 HTTP GET 요청을 보냅니다.
  • 이 요청에는 WebSocket으로 업그레이드하겠다는 의도가 포함되어 있으며, 헤더에 Connection: Upgrade, Upgrade: websocket 등이 명시됩니다.
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

서버의 응답

  • 서버는 클라이언트의 요청을 받아들이면 응답으로 101 Switching Protocols라는 상태 코드와 함께 WebSocket 연결을 승인합니다.
  • 또한, 클라이언트가 보낸 Sec-WebSocket-Key를 기반으로 새로운 값을 계산해 Sec-WebSocket-Accept 헤더로 반환합니다. 이를 통해 클라이언트는 서버의 응답이 유효한지 확인할 수 있습니다.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

2 ) 연결 확립 후 통신

핸드셰이크가 완료되면 WebSocket 연결이 확립되며, 이 시점부터는 클라이언트와 서버가 기존의 HTTP 요청/응답 사이클을 벗어나 양방향으로 데이터를 주고받을 수 있게 됩니다.

지속적인 연결

  • HTTP 연결은 일반적으로 요청을 완료한 후 닫히지만, WebSocket은 지속적으로 열린 상태로 유지됩니다. 이를 통해 서버나 클라이언트가 데이터를 보낼 준비가 될 때마다 언제든지 주고받을 수 있습니다.

프레임 기반 통신

  • WebSocket은 데이터를 작은 프레임 단위로 전송합니다. 이 프레임은 서버와 클라이언트 간에 서로 자유롭게 전달될 수 있으며, 텍스트나 바이너리 데이터를 포함할 수 있습니다.
  • 이러한 프레임에는 데이터 유형, 길이 정보, 종료 여부 등의 메타데이터가 포함되어 있어 효율적으로 데이터를 관리할 수 있습니다.

양방향 통신

  • 클라이언트와 서버 모두 같은 연결을 사용해 언제든지 메시지를 전송할 수 있습니다.
  • 예를 들어, 채팅 애플리케이션의 경우 클라이언트가 서버에 메시지를 보내면 서버는 즉시 다른 클라이언트에게 해당 메시지를 전송할 수 있습니다.

3 ) 데이터 전송 구조

WebSocket은 두 가지 주요 데이터 유형인 텍스트 메시지바이너리 메시지를 지원합니다. 데이터는 프레임이라는 작은 조각으로 나뉘어 전송되며, 다음과 같은 구조로 전송됩니다.

  • 프레임 헤더: 각 프레임에는 데이터 유형(텍스트 또는 바이너리), 프레임의 종료 여부 등을 포함하는 헤더가 있습니다.
  • 페이로드: 프레임의 나머지는 실제 데이터 페이로드로 구성됩니다. 이 페이로드는 전달하려는 메시지의 실제 내용입니다.

4 ) 연결 종료

WebSocket 연결은 클라이언트나 서버가 언제든지 종료할 수 있습니다. 종료 과정은 다음과 같습니다.

  • 종료 프레임 전송: 연결을 종료하고자 하는 쪽(클라이언트나 서버)은 "종료 프레임"을 전송하여 상대에게 연결을 닫겠다고 알립니다.
  • 확인 및 종료: 상대방은 이를 확인하고 연결을 닫습니다. 이후 모든 데이터 전송이 중단되고, 연결이 해제됩니다.

HTTP와 WebSocket 차이점

1 ) 통신방식

HTTP

  • HTTP는 요청-응답(Request-Response) 방식입니다. 클라이언트(웹 브라우저)가 서버에 요청을 보내면 서버는 그에 대한 응답을 반환합니다.
  • 클라이언트가 필요한 정보가 있을 때마다 서버에 요청을 보내고 서버는 한 번 응답한 후 연결을 종료합니다.
  • 이러한 방식 때문에 클라이언트는 서버의 상태 변화나 실시간 정보 수신을 위해 주기적으로 서버에 요청을 보내는 "폴링(Polling)"을 사용해야 합니다.

💡 Polling

웹소켓 등장 이전에 웹 애플리케이션에서 서버와 실시간으로 데이터를 주고받기 위해 주로 사용하던 방식 중 하나로 HTTP의 가장 큰 특징이자 단점이 될 수 있는 단방향 통신을 해결하기 위해 HTTP 프로토콜을 활용해 억지로 양방향 통신을 구현한 것입니다. 이 방식은 클라이언트(브라우저)가 일정한 시간 간격으로 서버에 데이터를 요청하여 서버의 상태나 업데이트된 정보를 확인하는 방식입니다.

WebSocket

  • WebSocket은 양방향 통신(Bi-directional) 을 지원하는 프로토콜입니다. 즉, 클라이언트와 서버가 서로 데이터 전송을 자유롭게 할 수 있습니다.
  • 한 번 연결이 설정되면 연결이 열린 상태로 유지되며, 서버와 클라이언트가 상호작용을 할 때마다 별도의 요청을 새로 보내지 않아도 됩니다.
  • 이를 통해 실시간 소통이 필요한 애플리케이션에서 매우 효율적입니다.

2 ) 연결 방식

HTTP

  • HTTP는 비연결형(Stateless) 프로토콜로, 각 요청은 독립적으로 이루어집니다. 클라이언트는 요청을 보낼 때마다 서버와 새로운 연결을 설정합니다.
  • 모든 요청마다 TCP 연결을 설정하고 응답 후 연결을 끊기 때문에 연결 오버헤드가 있습니다.

WebSocket

  • WebSocket은 연결형(Connection-oriented) 프로토콜입니다. 연결 초기화 단계에서 클라이언트와 서버는 HTTP 핸드셰이크(Handshake) 과정을 통해 연결을 업그레이드하고, 이후에는 지속적인 TCP 연결을 유지합니다.
  • 서버와 클라이언트 간에 연결이 유지되기 때문에 언제든 데이터를 보낼 수 있습니다.

3 ) 통신 방향

HTTP

  • 단방향 통신: 클라이언트가 요청을 보내면 서버가 응답하는 형태입니다. 서버는 클라이언트의 요청이 없는 한 클라이언트에게 정보를 보낼 수 없습니다.
  • 이를 극복하기 위해 서버가 클라이언트에게 데이터를 푸시하는 방법으로는 롱 폴링(Long Polling), 서버 센트 이벤트(Server-Sent Events, SSE) 등을 사용합니다. 그러나 이러한 방법들은 일정한 한계와 오버헤드가 존재합니다.

WebSocket

  • 양방향 통신: 클라이언트와 서버 모두 자유롭게 메시지를 보낼 수 있습니다. 서버가 상태 변화가 발생했을 때 클라이언트에게 즉시 알릴 수 있기 때문에 실시간 통신이 가능합니다.

4 ) 시간성과 효율성

HTTP

  • HTTP는 실시간 통신을 위해 클라이언트가 주기적으로 서버에 요청을 보내는 폴링 방식을 사용해야 합니다. 하지만 이 방식은 대역폭을 소모하고 서버에 부담을 줄 수 있습니다.
  • 클라이언트가 필요하지 않은 정보라도 지속적으로 요청해야 하는 비효율적인 측면이 있습니다.

WebSocket

  • WebSocket은 한 번 연결을 맺은 후 데이터를 양방향으로 자유롭게 주고받기 때문에 실시간성과 효율성이 뛰어납니다.
  • 연결이 유지되므로 필요할 때만 데이터가 오가며, 불필요한 연결 설정과 해제 과정이 없어 네트워크 자원을 절약할 수 있습니다.

5 ) 데이터 전송 구조

HTTP

  • HTTP는 요청과 응답마다 헤더가 포함되어 전송됩니다. 각 요청마다 상당한 양의 헤더 데이터가 추가되므로 오버헤드가 증가합니다.
  • 주로 HTML, JSON, 텍스트 데이터 등을 전송하며, 다량의 바이너리 데이터 전송에는 상대적으로 적합하지 않습니다.

WebSocket

  • WebSocket은 초기 핸드셰이크 이후에는 프레임 단위로 데이터를 전송하며, 헤더 오버헤드가 적습니다.
  • 텍스트 데이터바이너리 데이터 모두 효율적으로 전송할 수 있습니다.

특성HTTPWebSocket
통신 방식요청-응답양방향 통신
연결 유지비연결형, 요청 시마다 새 연결지속적 연결
통신 방향단방향 (클라이언트 → 서버)양방향 (클라이언트 ↔ 서버)
실시간성폴링이나 롱 폴링으로 실시간 구현 가능실시간 통신에 매우 적합
오버헤드각 요청에 헤더 포함핸드셰이크 이후 헤더 오버헤드 없음
활용 사례정적 콘텐츠 제공, 요청 기반 데이터실시간 채팅, 알림, 게임, IoT 등

WebSocket은 HTTP의 단방향성 한계를 극복하고, 실시간으로 양방향 소통이 필요한 상황에서 뛰어난 효율성과 성능을 제공합니다. 반면 HTTP는 간단한 요청-응답이 필요한 웹 콘텐츠 제공에 더 적합한 프로토콜입니다.


Ws WebSocket

ws는 Node.js에서 순수한 WebSocket 프로토콜을 구현하기 위한 가장 기본적인 라이브러리입니다. 매우 경량이며, WebSocket 표준을 직접 사용합니다. 불필요한 부가 기능 없이 간단한 실시간 통신을 구현하고자 할 때 적합합니다.


주요 객체 및 메서드

WebSocket.Server의 메서드와 이벤트

주요 객체

  • WebSocket.Server (WebSocket.Server): 서버를 생성하기 위한 객체입니다. 클라이언트와의 연결을 관리하며, 여러 이벤트 리스너를 설정하여 클라이언트와의 소통을 지원합니다.
  • WebSocket (WebSocket): 서버 또는 클라이언트 측에서 WebSocket 연결을 나타내는 객체입니다. 각 클라이언트와의 연결을 이 객체를 통해 처리합니다.

WebSocket.Server의 메서드와 이벤트

  • new WebSocket.Server(options): WebSocket 서버를 생성하는 생성자입니다. 여기서 options 객체를 통해 포트 번호와 같은 설정을 할 수 있습니다.
    const server = new WebSocket.Server({ port: 8080 });
  • server.on(event, callback): 특정 이벤트가 발생했을 때 실행할 콜백 함수를 설정합니다.
    • event는 아래와 같이 구성됩니다:

    • connection: 클라이언트가 연결될 때 발생합니다. 콜백 함수는 연결된 WebSocket 객체를 인자로 받습니다.

      server.on('connection', (socket) => {
        console.log('새 클라이언트가 연결되었습니다.);
      });
      
    • close: 서버가 종료되거나 연결이 종료될 때 발생합니다.

      server.on('close', () => {
        console.log('서버가 종료되었습니다.');
      });
    • error: 서버에서 오류가 발생했을 때 호출됩니다.

      server.on('error', (error) => {
        console.log(`에러가 발생했습니다: ${error.message}`);
      });

  • socket.send(data): 서버 또는 클라이언트가 상대방에게 데이터를 전송합니다. data는 문자열 또는 바이너리 형식일 수 있습니다.
    socket.send('안녕하세요, 클라이언트!');
  • socket.on(event, callback): 특정 이벤트에 대해 콜백을 설정합니다.
    • event는 아래와 같이 구성됩니다:

    • message: 상대방으로부터 메시지를 받을 때 발생합니다. 콜백 함수는 수신된 메시지를 인자로 받습니다.

      socket.on('message', (message) => {
        console.log(`받은 메시지: ${message}`);
      });
    • close: 연결이 닫힐 때 발생합니다.

      socket.on('close', () => {
        console.log('연결이 닫혔습니다.');
      });
    • error: 연결 중 오류가 발생할 때 호출됩니다.

      socket.on('error', (error) => {
        console.log(`에러가 발생했습니다: ${error.message}`);
      });
  • socket.close(): WebSocket 연결을 닫습니다. 연결이 닫히면 close 이벤트가 발생합니다.

WebSocket 객체는 addEventListener 메서드를 통해 다양한 이벤트에 리스너를 추가할 수 있습니다. 이 방식은 이벤트 리스너를 설정하는 또 다른 방법으로, 이벤트 기반 통신에서 자주 사용됩니다. onmessage, onopen, onclose 등 속성을 설정하는 방법과 비슷하지만, 이 방식은 이벤트 리스너를 여러 개 추가할 수 있다는 장점이 있습니다.

주요 이벤트

  • open: WebSocket 연결이 성공적으로 열렸을 때 발생하는 이벤트입니다.
  • message: 서버로부터 메시지가 도착했을 때 발생하는 이벤트입니다.
  • close: WebSocket 연결이 닫혔을 때 발생하는 이벤트입니다.
  • error: WebSocket 연결에서 오류가 발생했을 때 발생하는 이벤트입니다.
// WebSocket 서버에 연결
const socket = new WebSocket('ws://localhost:3000');

// 'open' 이벤트 리스너 추가
socket.addEventListener('open', (event) => {
  console.log('WebSocket 연결이 열렸습니다.');
  socket.send('서버에 메시지를 전송합니다.');
});

// 'message' 이벤트 리스너 추가
socket.addEventListener('message', (event) => {
  console.log(`서버로부터 받은 메시지: ${event.data}`);
});

// 'close' 이벤트 리스너 추가
socket.addEventListener('close', (event) => {
  console.log('WebSocket 연결이 종료되었습니다.');
});

// 'error' 이벤트 리스너 추가
socket.addEventListener('error', (event) => {
  console.error('WebSocket 오류 발생:', event);
});

Ws WebSocket 사용하기

ws 모듈을 사용하여 간단한 채팅을 구현한 예시입니다.

서버에 ws 모듈 설치하기

npm install ws

서버 코드

// backend/server.js
const WebSocket = require("ws");

// 포트 3000번에서 WebSocket 서버를 실행
const server = new WebSocket.Server({ port: 3000 });

// backend/server.js
server.on("connection", (ws) => {
  console.log("클라이언트가 연결되었습니다.");

  // 클라이언트로부터 메시지를 받았을 때
  ws.on("message", (message) => {
    console.log(`클라이언트로부터 받은 메시지: ${message}`);

    // 연결된 모든 클라이언트에게 메시지를 브로드캐스트
    server.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(message.toString()); // 메시지를 문자열로 전송
      }
    });
  });

  // 연결이 종료되었을 때
  ws.on("close", () => {
    console.log("클라이언트가 연결을 종료했습니다.");
  });

  // 클라이언트에게 초기 메시지 전송
  ws.send("웹소켓 서버에 연결되었습니다.");
});

클라이언트 코드

<!-- frontend/index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Socket.IO</title>
</head>
<body>
  <h1>Socket.IO</h1>
  <div id="chat">
    <div id="messages"></div>
    <input id="messageInput" type="text" placeholder="메시지를 입력하세요" />
    <button id="sendButton">전송</button>
  </div>

  <script>
    // 서버와 연결
    const socket = io('http://localhost:3000');

    socket.on('connect', () => {
      console.log('서버에 연결되었습니다.');
    });

    // 메시지 전송 버튼 클릭 시 메시지를 서버로 보냄
    document.getElementById('sendButton').addEventListener('click', () => {
      const messageInput = document.getElementById('messageInput');
      const message = messageInput.value;

      if (message.trim() !== '') {
        socket.emit('chat message', message); // 서버로 메시지 전송
        messageInput.value = ''; // 메시지 입력 필드 초기화
      }
    });

    // 서버로부터 받은 메시지를 화면에 표시
    socket.on('chat message', (message) => {
      const messagesDiv = document.getElementById('messages');
      const messageElement = document.createElement('div');
      messageElement.textContent = message;
      messagesDiv.appendChild(messageElement);
    });

    socket.on('disconnect', () => {
      console.log('서버와의 연결이 종료되었습니다.');
    });
  </script>
</body>
</html>

Socket.io

Web Socket은 HTML5의 기술이기 때문에오래된 버전의 웹 브라우저는 Web Socket을 지원하지 않습니다. 특히 자동 업데이트가 되지 않는 익스플로러 구 버전 사용자들은 Web Socket으로 작성된 웹페이지를 볼 수 없습니다. 따라서 이를 해결하기 위해 나온 여러 기술 중 하나가 Socket.io 입니다.웹페이지가 열리는 브라우저가 웹소켓을 지원하면 웹소켓 방식으로 동작하고,지원하지 않는 브라우저라면 일반 http를 이용해서 실시간 통신을 흉내내는 것입니다.

Socket.io는 자바스크립트를 이용하여 브라우저 종류에 상관없이 실시간 웹을 구현할 수 있도록 한 기술입니다. WebSocket뿐만 아니라 폴백 메커니즘을 사용하여 다양한 실시간 통신 방식(예: HTTP 폴링)을 지원합니다. WebSocket 프로토콜을 이용하지만, 추가적인 기능(브로드캐스팅, 룸, 자동 재연결 등)을 제공하여 실시간 통신을 구현하는 데 더 유연한 환경을 제공합니다.


주요 객체 및 메서드

주요 객체

  • Server (io): Socket.IO 서버 객체로, 여러 클라이언트와의 연결을 관리합니다.
  • Socket (socket): 개별 클라이언트와의 연결을 나타내는 객체로, 클라이언트와 서버 간의 통신을 담당합니다.

Server 객체의 메서드와 이벤트

  • require('socket.io')(port, options): 서버를 생성하며, 주어진 포트에서 실행합니다.
    const io = require('socket.io')(3000);
  • io.on(event, callback) : 이벤트 리스너를 설정합니다.
    • connection: 새로운 클라이언트가 연결되었을 때 호출됩니다. 콜백 함수는 연결된 클라이언트의 socket 객체를 인자로 받습니다.

      io.on('connection', (socket) => {
        console.log('새 클라이언트가 연결되었습니다.');
      });
  • io.emit(event, data): 연결된 모든 클라이언트에게 이벤트와 데이터를 전송합니다.
    io.emit('broadcast', '모든 클라이언트에게 메시지를 보냅니다.');

Socket 객체의 메서드와 이벤트

  • socket.on(event, callback): 특정 이벤트에 대해 콜백을 설정합니다.
    • message: 기본 이벤트로, 클라이언트가 서버에 데이터를 전송할 때 호출됩니다.
      socket.on('message', (data) => {
        console.log(`클라이언트로부터 받은 메시지: ${data}`);
      });
    • 커스텀 이벤트: 사용자 정의 이벤트를 설정하고 데이터 통신에 사용할 수 있습니다.
      socket.on('chat message', (msg) => {
        console.log(`받은 채팅 메시지: ${msg}`);
      });
  • socket.emit(event, data): 현재 연결된 클라이언트에게 이벤트와 데이터를 전송합니다.
    socket.emit('response', '서버로부터 응답 메시지');
  • socket.broadcast.emit(event, data): 현재 연결된 클라이언트를 제외한 나머지 모든 클라이언트에게 이벤트와 데이터를 전송합니다.
    socket.broadcast.emit('new user', '새 사용자가 접속하였습니다.');

네임스페이스와 룸

  • 네임스페이스 (io.of(namespace)): 네임스페이스는 서로 다른 목적의 통신 채널을 분리하기 위해 사용합니다.
    const chat = io.of('/chat');
    chat.on('connection', (socket) => {
      console.log('채팅 네임스페이스에 연결되었습니다.');
    });
  • 룸(Room): socket.join(room)과 같은 메서드를 사용하여 여러 클라이언트를 그룹화합니다.
    socket.join('room1');
    io.to('room1').emit('message', '룸1에 있는 모든 사용자에게 메시지 전송');

Socket.io 사용하기

Socket.IO 모듈을 사용하여 간단한 채팅을 구현한 예시입니다.

Socket.IO는 서버와 클라이언트 모두 설치가 필요합니다.

npm install socket.io socket.io-client

서버 코드

// backend/server.js
const io = require('socket.io')(3000, {
  cors: {
    origin: "*", // 모든 도메인에서 접근 허용 (개발용으로만 사용)
    methods: ["GET", "POST"]
  }
});

io.on('connection', (socket) => {
  console.log('클라이언트가 연결되었습니다.');

  // 클라이언트로부터 채팅 메시지를 받았을 때
  socket.on('chat message', (message) => {
    console.log(`클라이언트로부터 받은 메시지: ${message}`);

    // 연결된 모든 클라이언트에게 메시지를 브로드캐스트
    io.emit('chat message', message);
  });

  // 연결이 종료될 때
  socket.on('disconnect', () => {
    console.log('클라이언트가 연결을 종료했습니다.');
  });
});

클라이언트 코드

<!-- frontend/index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Socket.IO</title>
  <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
</head>
<body>
  <h1>Socket.IO</h1>
  <div id="chat">
    <div id="messages"></div>
    <input id="messageInput" type="text" placeholder="메시지를 입력하세요" />
    <button id="sendButton">전송</button>
  </div>

  <script>
    // 서버와 연결
    const socket = io('http://localhost:3000');

    socket.on('connect', () => {
      console.log('서버에 연결되었습니다.');
    });

    // 메시지 전송 버튼 클릭 시 메시지를 서버로 보냄
    document.getElementById('sendButton').addEventListener('click', () => {
      const messageInput = document.getElementById('messageInput');
      const message = messageInput.value;

      if (message.trim() !== '') {
        socket.emit('chat message', message); // 서버로 메시지 전송
        messageInput.value = ''; // 메시지 입력 필드 초기화
      }
    });

    // 서버로부터 받은 메시지를 화면에 표시
    socket.on('chat message', (message) => {
      const messagesDiv = document.getElementById('messages');
      const messageElement = document.createElement('div');
      messageElement.textContent = message;
      messagesDiv.appendChild(messageElement);
    });

    socket.on('disconnect', () => {
      console.log('서버와의 연결이 종료되었습니다.');
    });
  </script>
</body>
</html>

Ws vs Socket.io

wsSocket.IO는 모두 Node.js에서 WebSocket 프로토콜을 사용하여 클라이언트와 서버 간의 실시간 통신을 구현하는 라이브러리입니다. 그러나 이 둘은 기능적, 구조적, 사용 편의성 측면에서 차이가 있습니다.


1 ) 프로토콜 지원 방식

ws

  • ws는 순수한 WebSocket 프로토콜만을 구현하는 경량 라이브러리입니다. WebSocket 프로토콜만을 사용하기 때문에 직접 WebSocket 연결을 관리해야 합니다.
  • 브라우저가 WebSocket을 지원하지 않는 경우 다른 대체 통신 방식(폴링 등)을 사용할 수 없으므로, 모든 사용자가 WebSocket을 지원하는 환경에서 접속해야 합니다.

Socket.IO

  • Socket.IOWebSocket을 포함한 다양한 실시간 통신 방법을 자동으로 지원합니다. WebSocket을 기본으로 사용하지만, 클라이언트가 WebSocket을 지원하지 않는 경우 자동으로 HTTP 폴링 등의 방법으로 폴백(fallback)할 수 있습니다.
  • 따라서, 더 많은 사용자를 대상으로 높은 호환성을 보장합니다. 이 때문에 WebSocket을 지원하지 않는 오래된 브라우저나 네트워크 제약이 있는 환경에서도 동작할 수 있습니다.

2 ) 기능과 부가 기능

ws

  • ws순수한 WebSocket 연결만을 제공하기 때문에 매우 경량이고, 최소한의 기능만 포함되어 있습니다.
  • 기본적인 메시지 전송과 수신 기능만 제공하며, 자동 재연결이나 네임스페이스 같은 고급 기능은 직접 구현해야 합니다.

Socket.IO

  • Socket.IO는 다양한 부가 기능을 제공합니다
    • 자동 재연결: 연결이 끊어질 경우 클라이언트는 자동으로 재연결을 시도합니다.
    • 이벤트 기반 통신: 단순한 메시지뿐만 아니라 이벤트를 이름으로 정의하고 그에 따라 처리할 수 있습니다.
    • 네임스페이스(Namespaces): 같은 서버에서 여러 개의 별도 통신 채널을 제공할 수 있습니다. 예를 들어, 특정 주제에 대한 연결을 구분할 수 있습니다.
    • 룸(Rooms): 여러 클라이언트를 그룹화하여 한 번에 특정 그룹에 메시지를 보낼 수 있습니다. 이를 통해 브로드캐스트와 멀티캐스트가 가능합니다.
  • 이러한 부가 기능 덕분에 Socket.IO는 채팅 애플리케이션이나 게임과 같은 복잡한 실시간 애플리케이션을 구현할 때 매우 유용합니다.

3 ) 설정 및 사용 편의성

ws

  • ws는 WebSocket 표준에 매우 충실하여 간단하고 경량입니다. 따라서 설정과 사용이 비교적 간단하며, 초기에 WebSocket 프로토콜을 잘 이해하고 있는 개발자라면 사용하기 수월합니다.
  • 다만, 고급 기능(자동 재연결, 룸 등)을 구현할 때는 개발자가 직접 모든 로직을 작성해야 하기 때문에 추가적인 노력이 필요합니다.

Socket.IO

  • Socket.IO설정이 다소 복잡할 수 있지만, 다양한 기능을 손쉽게 활용할 수 있는 장점이 있습니다. 예를 들어, 서버에서 여러 클라이언트를 연결하고 특정 그룹에만 메시지를 보낼 때 별도의 복잡한 설정 없이도 룸 기능을 사용하면 쉽게 구현할 수 있습니다.
  • 클라이언트와 서버 간의 네트워크 상태 변화에도 자동으로 대응할 수 있는 기능들을 기본 제공하기 때문에 사용 편의성이 높습니다.

4 ) 브라우저 호환성과 폴백 메커니즘

ws

  • 브라우저의 WebSocket API를 직접 사용합니다. 따라서, WebSocket을 지원하지 않는 오래된 브라우저나 프록시 서버를 통해 접속하는 경우에는 제대로 동작하지 않을 수 있습니다.

Socket.IO

  • WebSocket을 지원하지 않는 환경에서도 자동으로 HTTP 폴링(HTTP long-polling) 등의 폴백 메커니즘을 사용해 연결을 유지합니다. 따라서 다양한 환경에서 동작이 보장됩니다.
  • 이러한 폴백 기능 덕분에 네트워크 환경이 불안정하거나 브라우저 호환성이 중요한 프로젝트에서 특히 유리합니다.

5 ) 데이터 전송 방식 및 오버헤드

ws

  • ws는 WebSocket 표준에 따른 프레임 단위의 전송을 사용하며, 데이터 오버헤드가 거의 없습니다. 매우 경량화된 프레임을 사용해 네트워크 부하를 줄일 수 있습니다.
  • 최소한의 헤더를 사용하므로 대역폭 사용량이 적고, 고성능을 요구하는 실시간 애플리케이션에 적합합니다.

Socket.IO

  • Socket.IO는 다양한 기능을 제공하는 만큼, 각 데이터 전송에 추가적인 프로토콜 오버헤드가 발생합니다. 이벤트의 이름이나 데이터 구조 관리 등의 부가적인 데이터를 포함해 전송하기 때문에 기본 ws 라이브러리에 비해 오버헤드가 큽니다.
  • 이러한 오버헤드는 다수의 클라이언트가 접속하는 대규모 서비스에서는 성능에 영향을 줄 수 있지만, 일반적인 상황에서는 큰 문제가 되지 않습니다.

특성wsSocket.IO
프로토콜WebSocket만 지원WebSocket + 폴백 메커니즘 (HTTP 폴링 등)
기능기본적인 WebSocket 기능 제공이벤트 기반 통신, 자동 재연결, 룸, 네임스페이스 등
설정 편의성간단하고 경량설정이 다소 복잡하나 다양한 기능 지원
호환성브라우저에서 WebSocket만 사용 가능폴백 기능을 통해 호환성 높음
오버헤드최소한의 데이터 오버헤드부가적인 데이터 오버헤드 발생
사용 예시간단한 실시간 데이터 전송채팅, 게임 등 복잡한 실시간 애플리케이션

ws는 단순하고 가벼운 실시간 애플리케이션에 적합하고, Socket.IO는 더 복잡한 기능을 손쉽게 구현할 수 있어 다양한 요구사항을 가진 실시간 시스템에서 유리합니다.

profile
함께 개선하는 프론트엔드 개발자

0개의 댓글