포시코딩

1월25일 - WebSocket -> socket.io 변경을 하며 본문

TIL

1월25일 - WebSocket -> socket.io 변경을 하며

포시 2023. 1. 25. 19:44
728x90

개요

오늘은 기존에 WebSocket으로 구현했던 신청 알림 기능을

socket.io로 바꾸는 과정을 진행했다.

 

기존 WebSocket로 만든 코드

SocketManager.js

const http = require('http');
const WebSocket = require('ws');

class SocketManager {
  constructor(app) {
    this.server = http.createServer(app);
    this.wss = new WebSocket.Server({ server: this.server });
    this.load();
  }
  static sockets = [];

  load = () => {
    this.wss.on('connection', (socket) => {
      SocketManager.sockets.push(socket);
    });
  };

  static alertNewOrder = () => {
    SocketManager.sockets.forEach((aSocket) => {
      const data = {
        type: 'newOrder',
        payload: true,
      };
      aSocket.send(JSON.stringify(data));
    });
  };
}

module.exports = SocketManager;

alert.js

<script>
  const socket = new WebSocket(`ws://${window.location.host}`);

  socket.addEventListener('open', () => {
    console.log('Connected to Server ✅');
  });
  socket.addEventListener('close', () => {
    console.log('Disconnected to Server ❌');
  });

  socket.addEventListener('message', (message) => {
    const data = JSON.parse(message.data);
    if (data.payload) {
      document.querySelector('#alertNewOrder').classList.add('show');
      setTimeout(() => {
        document.querySelector('#alertNewOrder').classList.remove('show');
      }, 5000);
    }
  });
</script>

 

문제 발생

alert.js

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

  socket.on('newOrder', (payload) => {
    document.querySelector('#alertNewOrder').classList.add('show');
    setTimeout(() => {
      document.querySelector('#alertNewOrder').classList.remove('show');
    }, 5000);
  })
</script>

SocketManager.js

const http = require('http');
const SocketIO = require('socket.io');

class SocketManager {
  constructor(app) {
    this.server = http.createServer(app);
    this.wsServer = SocketIO(this.server);
    this.load();
  }

  load = () => {
    this.wsServer.on('connection', (socket) => {
      
      // 밑의 alertNewOrder일 때 실행되는 코드가 여기 있어야 되야될 것 같은데
      
    });
  };

  static alertNewOrder = () => {
    console.log(this.wsServer);  // undefined
    this.wsServer.sockets.emit('newOrder', true);
    // wsServer를 찾을 수 없어 에러 발생
  };
}

module.exports = SocketManager;

바꾸는 과정에서 문제를 겪었는데

socket.io 객체인 wsServer가 다른 서비스에서 호출하고 있는 alertNewOrder 함수에서

자꾸 undefined가 뜨는 것이었다.

 

프론트엔드쪽 코드는 문제없이 바꿨고 백엔드 코드를 어떻게 바꿀지 고민하다가

WebSocket 구현할 때도 사용한 static 변수를 사용하기로 했다.

 

해결 - static 변수 적용 후 

SocketManager.js

const http = require('http');
const SocketIO = require('socket.io');

class SocketManager {
  constructor(app) {
    this.server = http.createServer(app);
    SocketManager.wsServer = SocketIO(this.server);
    this.load();
  }
  static wsServer;

  load = () => {
    SocketManager.wsServer.on('connection', (socket) => {});
  };

  static alertNewOrder = () => {
    SocketManager.wsServer.sockets.emit('newOrder', true);
  };
}

module.exports = SocketManager;

socket.io 객체인 wsServer를 static으로 만든 후 직접 클래스를 통해 사용하는 방식으로 변경하여

해결할 수 있었다.

 

서버가 실행되며 생성자를 통해 만들어 지고나서 

다시 클래스를 인스턴스화 시키면 안되는 까다로운 문제였는데

이렇게 static을 활용하여 쉽게 다른 서비스에서도 접근하여 사용할 수 있었다.

728x90

'TIL' 카테고리의 다른 글

1월27일 - 궁금증 해결  (0) 2023.01.27
1월26일 - console.log 자동완성, 객체 구조 분해 할당 재작명  (3) 2023.01.26
1월24일 - DB time zone  (0) 2023.01.24
1월23일 - console.log, alert  (0) 2023.01.23
1월22일 - helmet  (1) 2023.01.22