Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

리액트 & socket.io 기반 채팅 어플리케이션 만들기 - 서버 편 본문

💻 백엔드/Node.js

리액트 & socket.io 기반 채팅 어플리케이션 만들기 - 서버 편

Chamming2 2021. 2. 3. 16:28

socket.io를 활용하면 사용자간 실시간 양방향 통신 어플리케이션을 만들 수 있습니다.

오늘은 socket.io / Express / React 스택을 활용해 채팅 어플리케이션을 제작해 보도록 하겠습니다.

[제작할 기능]

- 방, 유저네임 설정

- 방 입장 시 유저 입장 알림

- 유저간 채팅

- 방 퇴장 시 유저 퇴장 알림

1. 디펜던시 설치

- npm 또는 yarn을 활용해 먼저 express 와 socket.io 를 설치해줍니다.

npm i express socket.io
// 또는 yarn add express socket.io

2. 코드 작성

이후, server.js 파일을 생성하고 다음과 같이 코드를 작성합니다.

// server.js
const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const port = 5000; // 서버를 열 포트 번호
const app = express();

const server = http.createServer(app);
const io = socketIO(server);

io.on("connection", (socket) => {
});

server.listen(port, () => console.log(`Listening on port ${port}`));

본격적으로 socket.io를 활용하기 전에 알아두면 아주 좋은 규칙이 있습니다.

 

1. io는 서버 객체, socket은 클라이언트 객체이다.

2. on 은 이벤트를 받는 메서드, emit은 이벤트를 쏘는 메서드이다.

3. 일부 이벤트에 대응하는 콜백 함수의 인자는 지정되어 있다. 

(Ex. connect / connection, disconnect / disconnecting 이벤트의 인자는 소켓(클라이언트) 객체입니다.)

 

예를 들어 위 코드의 io.on("connection", callback) 은 "서버가 connection 이벤트를 받으면 콜백을 수행한다." 로 해석할 수 있겠죠?

 

이제 서버를 열었으니 먼저 방을 개설하는 기능을 추가해 봅시다.

const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const port = 5000;
const app = express();

const server = http.createServer(app);
const io = socketIO(server);

io.on("connection", (socket) => {
  socket.on("onJoin", ({ roomName: room, userName: user }) => {
    socket.join(room);
    io.to(room).emit("onConnect", `${user} 님이 입장했습니다.`);
});

server.listen(port, () => console.log(`Listening on port ${port}`));

한 가지 중요한 점으로 socket.io는 예약된 이벤트와 커스텀 이벤트를 활용해 이벤트 기반 프로그래밍을 수행하는데, 헷갈리지 않도록 제가 임의로 지정한 이벤트는 on- 접두사를 붙일 것입니다.

 

이제 클라이언트가 onJoin 이라는 이벤트를 쏘면 서버는 이를 받아 콜백을 수행합니다.

그리고 콜백에는 socket.join(room) 이라는 구문이 있는데, 문자 그대로 room 이라는 방에 들어가겠다는 의미입니다.

 

성공적으로 방에 들어가면 room 이라는 방에 있는 클라이언트에 onConnect 이벤트와 사용자가 입장했다는 메시지를 전송합니다.

이제 사용자간 채팅 메시지를 전송하는 기능을 추가해 봅시다.

const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const port = 5000;
const app = express();

const server = http.createServer(app);
const io = socketIO(server);

io.on("connection", (socket) => {
  socket.on("join", ({ roomName: room, userName: user }) => {
    socket.join(room);
    io.to(room).emit("onConnect", `${user} 님이 입장했습니다.`);
    
    socket.on("onSend", (messageItem) => {
      io.to(room).emit("onReceive", messageItem);
    });
});

server.listen(port, () => console.log(`Listening on port ${port}`));

(다음에 제작할) 클라이언트에서 메시지를 보내면 onSend 이벤트와 메시지 객체를 서버로 쏠텐데, 서버는 전달받은 메시지를 방 안의 모든 클라이언트에 쏴줘야 합니다.

 

이를 위해 클라이언트로부터 받은 messageItem 매개변수를 onReceive 이벤트 콜백의 인자로 넣어 주면, 채팅 기능도 벌써 끝입니다.

마지막으로 사용자가 방에서 나갈 때 발생하는 이벤트를 추가해 봅시다. 

const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const port = 5000;
const app = express();

const server = http.createServer(app);
const io = socketIO(server);

io.on("connection", (socket) => {
  socket.on("join", ({ roomName: room, userName: user }) => {
    socket.join(room);
    io.to(room).emit("onConnect", `${user} 님이 입장했습니다.`);
    
    socket.on("onSend", (messageItem) => {
      io.to(room).emit("onReceive", messageItem);
    });
    
    socket.on("disconnect", () => {
      socket.leave(room);
      io.to(room).emit("onDisconnect", `${user} 님이 퇴장하셨습니다.`);
    });
});

server.listen(port, () => console.log(`Listening on port ${port}`));

disconnect는 제가 임의로 생성한 이벤트가 아닌, 소켓이 서버와 연결이 끊어질 때 발생하는 예약 이벤트입니다.

사용자와 채팅 서버와의 연결이 끊어지면 socket.leave() 를 통해 연결을 확실히 종료한 후, 방에 퇴장 문구를 출력함으로써 채팅 서버 구현은 끝이 납니다.

 

뭐가 이렇게 금방 끝나냐고요?

진짜 고생은 클라이언트부터 시작됩니다...

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆