[Node.js] 실시간 채팅 기능 구현하기 1. Web Socket vs Socket I/O

jiyehyeon·2023년 2월 28일
0
post-thumbnail

실시간 채팅, 실시간 업데이트 등을 구현할 때 서버와 클라이언트 간 실시간 소통을 위해 WebSocket 또는 Socket.IO를 사용한다.

일반적인 HTTP 프로토콜은 클라이언트가 서버로 요청을 보냈을 때, 서버가 그 요청에 응답하는 구조다.
클라이언트의 요청 없이는 서버에서 클라이언트로 데이터를 전송할 수 없다.

하지만 WebSocket과 Socket.IO는 클라이언트와 서버 간에 한 번 연결이 성사되면 클라이언트의 요청 없이도 서버가 아무 때나 클라이언트로 데이터를 전송할 수 있다.

그렇다면 WebSocket과 Socket.IO는 뭐가 다를까?

WebSocket

웹소켓은 특수 프로토콜 wss를 사용해 연결을 생성할 수 있다.
ws 프로토콜도 있는데, 이를 사용하면 암호화되지 않은 패킷이 전송되므로 반드시 wss를 쓰는 것을 권장한다.

통신은 on, send, close 메서드를 기반으로 이루어진다.
on 메서드의 'connection' 이벤트를 통해 소켓을 열고, 'message' 이벤트의 콜백으로 데이터를 받는다.

전달하는 객체의 키값으로 데이터를 구분해야 한다.

// back

import { WebSocketServer } from "ws";

const server = new WebSocketServer({ port: 3000 });

// 웹소켓 서버 실행
server.on("connection", (socket) => {
  // 클라이언트로 메세지 전송
  socket.send(JSON.stringify({
    type: "hello from server",
    content: [ 1, "2" ]
  }));

  // 클라이언트로부터 메세지 수신
  socket.on("message", (data) => {
    const packet = JSON.parse(data);

    switch (packet.type) {
      case "hello from client":
        // ...
        break;
    }
  });
});
// front

const socket = new WebSocket("ws://localhost:3000");

socket.addEventListener("open", () => {
  // 서버로 메세지 전송
  socket.send(JSON.stringify({
    type: "hello from client",
    content: [ 3, "4" ]
  }));
});

// 서버로부터 메세지 수신
socket.addEventListener("message", ({ data }) => {
  const packet = JSON.parse(data);

  switch (packet.type) {
    case "hello from server":
      // ...
      break;
  }
});

Socekt IO

Socket IO는 Web Socket을 부분적으로 사용하는 프레임워크다.
프로토콜이 아닌, 프레임워크다.
여러 통신 기술들을 쉽게 사용할 수 있게 해주는 프레임워크다.

Web Socket과 달리 브라우저, 디바이스에 상관 없이 모든 환경에서 양방향 실시간 통신이 가능하다.
브라우저가 Web Socket을 지원할 경우 Web Socket을 사용하고,
지원하지 않을 경우 HTTP Long Polling 등 기타 통신을 지원한다.

또한, 연결이 끊길 경우에도 자동으로 재연결을 시도한다.

// back

import { Server } from "socket.io";

const io = new Server(3000);

io.on("connection", (socket) => {
  // send a message to the client
  socket.emit("hello from server", 1, "2", { 3: Buffer.from([4]) });

  // receive a message from the client
  socket.on("hello from client", (...args) => {
    // ...
  });
});
// front

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

const socket = io("ws://localhost:3000");

// send a message to the server
socket.emit("hello from client", 5, "6", { 7: Uint8Array.from([8]) });

// receive a message from the server
socket.on("hello from server", (...args) => {
  // ...
});

WebSocket에서는 "message"이벤트를 통해서만 데이터를 주고받을 수 있었다.

하지만 Socket IO는 사용자 정의 이름의 이벤트를 발생시키고, 매개변수 또한 갯수와 타입에 관계없이 주고받을 수 있다.

참고 자료
🎥 https://nomadcoders.co/noom/lectures/3099
📄 https://socket.io/docs/v4/
📄 https://ko.javascript.info/websocket

profile
https://github.com/jiyehyeon

0개의 댓글