본문으로 바로가기

socket.io/docs/v4

 

Introduction

What Socket.IO isSocket.IO is a library that enables real-time, bidirectional and event-based communication between the browser and the server. It consists of: a Node.js server: Source | API a Javasc

socket.io

 

ws을 이용해 웹 소켓을 사용할 수 있지만 Socket.IO에 편의 기능이 많아서 편리합니다.

 

사실 socket.io는 웹 소켓이 아니라, 웹 소켓을 사용할 수 없는 브라우저에서는 폴링을 사용하는 등, 실시간 통신을 구현할 수 있는 여러가지를 합쳐서 추상화 시켜놓은 패키지입니다.

 

그런데 큰 규모라면 사용을 비추천한답니다. "웹브라우저와 서버가 통신할 일이 아니면 굳이 socket.io일 필요는 없다."는게 중론입니다.
socket.io의 이점은 프로토콜 추상화라고 할 수 있겠죠...  protocol cycle에서 나오는 이슈 신경안써도 된다는거나 room 같은거 제공되는거 장점일순 있지만 애초에 네트워크 프로그래밍을 하는 프로그래머라면 이 정돈 그냥 뚝!딱! 만든다고 한다.

 

⚡ 설치

npm i socket.io

 

⚡ 사용

 

./app.js

const webSocket = require("./socket");

// listen
const server = app.listen(process.env.PORT, () => {
  return console.log(`success on : http://localhost:${process.env.PORT}`);
});

// ws는 http와 동일 포트를 사용함
webSocket(server);

 

./socket.js 

 

위 app.js에서 등록한 server 메서드를 작성해봅시다.

서버 객체를 받아서 소켓 객체를 생성하고 프론트가 접속할 경로(path)를 만들어 둡시다.

const SocketIO = require("socket.io");

module.exports = (server) => {

  // path 변수는 백엔드랑은 아무 관련 없음
  // 이는 클라이언트가 /socket.io 경로 접근시 소켓 연결을 시작함을 의미
  const io = SocketIO(server, { path: "/socket.io" });

  // 연결시 connection 이벤트 발생한 후 콜백 실행
  io.on("connection", (socket) => {
  
    // ws에 req가 따로 있었다면 socket에서는 socket.request에 존재합니다
    
    const req = socket.request;
    const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
    console.log(
      `✔ ${ip} 클라이언트 접속, socket.id : ${socket.id}, req.ip : ${req.ip}`
    );

    // 연결 해제
    socket.on("disconnect", () => {
      console.log(`${ip} 클라이언트 접속 해제. socket.id : ${socket.id}`);
      clearInterval(socket.interval);
    });

    // 에러
    socket.on("error", (error) => {});

    // 프론트 단에서 넘긴 메세지의 키값을 받습니다
    socket.on("from client", (data) => {
      console.log(data);
    });

    socket.interval = setInterval(() => {
      //메세지를 보내는 emit 메서드는 키, 값을 파라미터로 받습니다
      socket.emit("from server", "hello. this is message from server");
    }, 3000);
  });
};

 

소켓 객체에는 이벤트를 달아둡니다.

connection 이벤트, disconnet이벤트, err 이벤트는 기본 내장 이벤트이고

from client 는 직접 만든 이벤트입니다. 이벤트를 기준으로 소켓 통신이 이루어집니다.

 

req 객체는 socket.request로 참고할 수 있으며

소켓과 통신하는 클라이언트는 socket.id 를 통해 구별할 수 있습니다.

 

 

./views/index.pug

클라이언트 단의 socket.io는 socket.io/docs/v4/client-installation/ 부분을 참고해보세요

 

소켓 통신을 이용하기 위해서 클라이언트 단에서는 /socket.io 경로로 이동하여 socket.io.js를 실행해야 합니다.

이 외에도 socket.io-client 패키지를 설치하는 방법도 있긴 하지만, 우선은 간단히 아래처럼 해봅시다.

<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io();
</script>

 

그렇게 되면 io 객체를 이용할 수 있게 됩니다. 여기서 앞서 소켓 객체에서 path를 /socket.io로 설정했으므로 socket 객체를 만들 때 path 속성에 /socket.io를 등록합시다.

 

또, 웹소켓 통신을 통신이 시작되기 전 http 통신을 통해 웹소켓을 사용 가능한 브라우저 환경인지 탐지를 먼저 하고, 웹소켓이 불가능한 환경이면 폴링으로 통신을 합니다. 만약 폴링을 사용하지 않고 웹소켓이 아니면 통신 자체를 하지 못하게 하려면 tansports 속성에 ['websocket']을 지정해주면 됩니다.

extends layout

block content
  div 개발자 도구 확인하십쇼.
  script(src="/socket.io/socket.io.js")
  script.
    
    // connect하는 것이므로 첫 인자에는 소켓 통신을 시도하는 웹서버의 주소를 입력해줍시다.
    
    const socket = io.connect("http://localhost:3000", {
      //- path 변수는 백단에서 준 path값과 동일해야 함
      path: "/socket.io",
      
      // transports로 다음 값을 주면 폴링을 시도하지 않고 웹소켓만으로 통신합니다
      transports: ['websocket']
    });
    
    // 백단에서 emit의 키값과 동일한 값을 줘야 합니다
    socket.on("from server", (data) => {
      console.log(data)
      socket.emit("from client", "Hello from client")
      
    });

 

소켓 통신이 이뤄진 것을 볼 수 있습니다. ws 와는 다르게 키와 값이 동시에 들어있는 것을 확인할 수 있습니다.

서버의 콘솔에 출력된 결과도 다음과 같음을 확인할 수 있습니다. socket.id를 통해 클라이언트를 구분할 수도 있습니다.

const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
console.log(
  `✔ ${ip} 클라이언트 접속, socket.id : ${socket.id}, req.ip : ${req.ip}`
);

✔ ::1 클라이언트 접속, socket.id : 25GJNosDna87tVd2AAAA, req.ip : undefined

 

 

 

 

⚡ emit로 보내고 on으로 받는다.

 

  정리하자면, emit로 메세지를 보낼 때 사용하는 키, 값에서 키는 해당 메세지를 받는 표식이며 값은 data입니다. socket.on("보낸 쪽에서 지정한 key", (data) => {console.log(data)})와 같이 사용됩니다.

 

  emit로 보내고 on으로 받는다.

 

  이걸 기억합시다


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체