node.js

(node.js + React) + Socket.io 간단한 연결 구현 (+ TypeScript)

판교너굴맨 2021. 6. 25. 19:53

이번 스프린트에 실시간 양방향 통신 기능이 필요해서 Socket.io로 구현하게 되었다.

Socket.io란?

Socket.io는 양방향 통신을 가능하게 하는 WebSocket 기반의 라이브러리이다.

공식 문서: https://socket.io/get-started/chat

Socket.IO는 실시간 웹 애플리케이션을 위한 이벤트 기반 라이브러리이다. 웹 클라이언트와 서버 간의 실시간 양방향 통신을 가능케 한다. 

출처: 위키백과

 

서버 측 구현 (Node Express)

1. Typescript 실행환경 세팅

2022.06.23 - [node.js] - [node.js] node.js + typescript 실행환경 세팅하기

 

[node.js] node.js + typescript 실행환경 세팅하기

node.js를 사용할 사이드 프로젝트 아이디어가 생각이 나지 않아 일단 개발 서버 환경부터 만들어 두려고 한다. Node.js 설정 0. Nodejs란 Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니.

myung-ho.tistory.com

위 게시물의 package.json에 index.ts를 app.ts로 바꿔서 작업해주자.

2. ES Modules 사용

Typescript를 사용하면 별다른 설정 없이 ES Modules 방식을 사용할 수 있다.

2021.06.27 - [JavaSctipt] - [Javascript] ES Modules 방식

 

[Javascript] ES Modules 방식

node.js 보다 react를 먼저 접했던 나는 Commonjs 방식 보다 ES Modules 방식이 더욱 익숙했다. 그래서 node.js도 ES Modules 방식으로 사용하기 위해 찾아본 내용을 간단하게 정리해보려고 한다. Commonjs 방식 :.

myung-ho.tistory.com

3. Express 설치

#npm
npm i express @types/express
#yarn
yarn add express @types/express

4. 코드 구현

app.ts

import express from 'express';
import http from 'http';
import socket from './socket';

const PORT = 3010;

const app = express();
const server = http.createServer(app);

socket(server);
server.listen(PORT, () => console.log(`app listening on port ${PORT}!`));

우리가 만들 socket 함수에 http server를 파라미터로 넣어준다.

 

socket.ts

import http from 'http';
import { Server } from 'socket.io';

let interval: number = 3000;

const socket = (server: http.Server) => {
  const io = new Server(server, {
    cors: {
      origin: '*'
    }
  });

  io.on('connection', socket => {
    console.log('New client connected');

    socket.on('disconnect', () => console.log('user disconnect', socket.id));

    socket.on('good', (data: any) => {
      console.log(data); // 클라이언트 -> 서버
    });

    setInterval(() => {
      socket.emit('hi', '서버 -> 클라이언트');
    }, interval);
  });
};

export default socket;

 

받아온 http server를 socket.io에 할당해서 새 인스턴스를 생성한다. 그리고 cors 설정을 해준다.

2022.02.05 - [개발공부 & Network & OS] - [Web] SOP와 CORS

 

connection : 클라이언트가 접속했을 때 발생하고, 콜백으로 소켓 객체를 제공.

disconnect :  클라이언트가 연결을 끊었을 때 발생하는 함수

good : 클라이언트에서 good이라는 커스텀 이벤트명으로 데이터를 보낼 때 서버에서 받는 부분

(클라이언트 -> 서버)

emit :  3초마다 클라이언트에게 메세지를 보내는 부분, 첫 번째 인자는 이벤트 이름, 두 번째 인자는 데이터이다.

위에서 hi라는 이벤트 이름으로 hello라는 데이터를 3초마다 보내게 된다. 클라이언트가 이 메시지를 받기 위해서는 hi에 대한 이벤트 리스너를 만들어야 한다.

(서버 -> 클라이언트)

 

클라이언트 측 구현 (React)

1.socket.io-client 설치

공식 문서: https://socket.io/docs/v4/client-api/

yarn add socket.io-client

2. 코드 구현

App.ts

import React from 'react';
import { io } from 'socket.io-client';

let interval = 3000;
export default function App() {
  const onSocket = () => {
    const socket = io('http://localhost:3010');

    setInterval(() => {
      socket.emit('good', '클라이언트 -> 서버');
    }, interval);

    socket.on('hi', (data) => console.log(data)); // 서버 -> 클라이언트
  };

  return <button onClick={onSocket}>socket 통신 시작</button>;
}

3. 동작 확인

socket 통신 시작 버튼을 클릭하면 3초마다 서버에서 클라이언트로 데이터를 받는 걸 확인할 수 있다.

반대로 서버에서도 3초마다 클라이언트에서 데이터를 받아오는 걸 확인할 수 있다.

 

번외 transports: ['websocket']

socket.io는 첫 연결 때 Polling( http로 실시간 데이터 전송 방법)으로 연결하고 웹소켓을 사용할 수 있는 환경이면 websocket으로 업그레이드한다.

만약 처음부터 Polling 방식이 아닌 WebSocket 방식으로 연결하려면 transports: ['websocket']를 추가한다.

import React from 'react';
import { io } from 'socket.io-client';

let interval = 3000;
export default function App() {
  const onSocket = () => {
    const socket = socketIOClient('http://localhost:3010', {
      transports: ['websocket']
    });

    setInterval(() => {
      socket.emit('good', '클라이언트 -> 서버');
    }, interval);

    socket.on('hi', (data) => console.log(data)); // 서버 -> 클라이언트
  };

  return <button onClick={onSocket}>socket 통신 시작</button>;
}