티스토리 뷰

자바스크립트

Node.js와 ws로 직접 WebSocket 서버 만들기

YG - 96년생 , 강아지 있음, 개발자 희망 2023. 1. 15. 12:38

 

 

1. 설치하기

 

npm i ws

 

 

 

 

ws

Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js. Latest version: 8.12.0, last published: 6 days ago. Start using ws in your project by running `npm i ws`. There are 14226 other projects in the npm registry using ws

www.npmjs.com

 

 

2. Node.js 환경에서 WebSocket 서버 만들기

 

WebSocket 환경에서의 서버만 사용한다면 아래의 코드처럼 만들 수 있습니다.

 

import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function message(data) {
    console.log('received: %s', data);
  });

  ws.send('something');
});

 

 

저의 경우 http와 ws를 함께 사용할 것이기 때문에 아래와 같은 코드로 작성하였습니다.

 

import { createServer } from 'http';
import express from 'express';
import { WebSocketServer } from 'ws';

const app = express();

const handleListen = () => {
  console.log(`서버가 켜졌습니다. http://localhost:3000/`);
};

const server = createServer(app);

const wss = new WebSocketServer({ server });

server.listen(3000, handleListen);

 

 

3. 프론트와 백앤드 연결하기

 

백앤드

server.js

wss.on('connection', handleConnection);

 

프론트

 

 

WebSocket - Web API | MDN

WebSocket 객체는 WebSocket 서버 연결의 생성과 관리 및 연결을 통한 데이터 송수신 API를 제공합니다.

developer.mozilla.org

app.js

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


or 

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

 

 

이렇게 하면 연결이 됩니다.

 

console.log(socket)

 

 

 

4. 연결 후 백앤드와 프론트의 양방향 통신

 

 

백앤드

server.js

import { createServer } from 'http';
import express from 'express';
import { WebSocketServer } from 'ws';
import { MESSAGE_TYPE } from './constant/chat.js';

const app = express();

const handleListen = () => {
  console.log(`서버가 켜졌습니다. http://localhost:3000/`);
};

const server = createServer(app);

const wss = new WebSocketServer({ server });

const sockets = [];

wss.on('connection', (socket) => {
  sockets.push(socket);
  socket[MESSAGE_TYPE.nickname] = '익명';
  console.log('브라우저와 연결되었습니다.😀');
  wss.on('close', () => {
    console.log('브라우저와 연결이 끊어졌습니다.😡');
  });
  socket.on('message', (msg) => {
    const message = JSON.parse(msg);
    if (message.type === MESSAGE_TYPE.message) {
      sockets.forEach((socketElement) => {
        socketElement.send(`${socketElement.NICKNAME}: ${message.payload}`);
      });
    } else if (message.type === MESSAGE_TYPE.nickname) {
      socket[MESSAGE_TYPE.nickname] = message.payload;
    }
  });
});

server.listen(3000, handleListen);

 

프론트

chat.js

import { MESSAGE_TYPE } from '../constant/chat.js';

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

const nickForm = document.querySelector('.nickname');
const msgForm = document.querySelector('.message');
const msgList = document.querySelector('.msgList');

const makeMessage = (type, payload) => {
  const msg = { type, payload };
  return JSON.stringify(msg);
};

const handleNickSubmit = (event) => {
  event.preventDefault();
  const input = nickForm.querySelector('input');
  socket.send(makeMessage(MESSAGE_TYPE.nickname, input.value));
  input.value = '';
};

const handleMsgSubmit = (event) => {
  event.preventDefault();
  const input = msgForm.querySelector('input');
  socket.send(makeMessage(MESSAGE_TYPE.message, input.value));
  input.value = '';
};

socket.addEventListener('open', () => {
  console.log('서버와 연결되었습니다.😀');
});

socket.addEventListener('close', () => {
  console.log('서버와 연결이 끊어졌습니다.😡');
});

socket.addEventListener('message', (msg) => {
  console.log(msg);
  const li = document.createElement('li');
  li.innerText = msg.data;
  msgList.append(li);
});

msgForm.addEventListener('submit', handleMsgSubmit);
nickForm.addEventListener('submit', handleNickSubmit);

 

상수 관리

constant/chat.js

const MESSAGE_TYPE = Object.freeze({
  message: 'MESSAGE',
  nickname: 'NICKNAME',
});

export { MESSAGE_TYPE };

닉네임과 메세지를 프론트에서 볼 수 있음

 


저는 ws를 이용하여 직접 WebSocket 서버를 만들어 보았는데 Socket.io를 이용하여 이미 다 구현된 기능을 가져다 사용하는 것도 좋은 방법인 것 같습니다.

 

그 이유는 채팅방에서 유저가 사라지면 sockets 배열에서 빠진 유저를 찾아서 삭제를 해줘야 하는 등 여러 구현해야 할 것들을  개발자 입장에서는 이미 구현되어 있는 Socket.io가 더 편하게 느껴지기 때문입니다. 그렇지만 Socket.io 또한 ws의 기능들을 이용하여 만들어진 것이기에 ws를 알고 있으면 응용하기 좋을 것  같습니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함