본문 바로가기
개발 Study/Node

[SocketIO/WebRTC] 줌 클론 코딩(1) - Socket.io로 채팅 만들기

by jiyoon_92 2022. 8. 22.
반응형

노마드 코더 [Javascript] 기초 - 줌 클론 코딩


코딩쟁이들이라면 들어봤을 법한 유튜버 '노마드 코더' Javascript 무료 강의로 아래 사이트에 들어가면 볼 수 있다.

https://nomadcoders.co/noom

 

줌 클론코딩 – 노마드 코더 Nomad Coders

WebSockets, SocketIO, WebRTC

nomadcoders.co

코로나로 인해 비대면 미팅이 늘어난 시점에 Zoom 은 샛별같이 등장하여 화상 채팅 시장을 장악했다. Socket.io를 이용하여 실시간 채팅 및 스트리밍 영상을 주고받을 수 있는 화상 채팅 서비스를 만들어보는 강의다.

전에 하다가 중단한 실시간 채팅 구현하기에서 이미 Socket.io를 이용하여 구현했지만 제대로 강의를 듣고 기초부터 다시 다져서 기존 코드를 리팩토링하는 계기를 만들고 싶다.

80% 정도 듣고 쓰는 이 리뷰는 내가 지치거나 까먹기 전에 동기부여 용으로 남긴다.


1. WebSocket vs Socket.io

1-1. Socket 으로 메시지 전송

// WebSocket
aSocket.send(message.data); 
// Socket.io
socket.emit("nickname", input.value);

메시지를 전송할 때 사용하는 함수가 다르며, send()로 보낼 경우 blob.data로 보내질 경우가 있으며 이를 변환해서 처리해야한다. emit의 경우 string만 주고받는다. 

1-2. Socket 관리

WebSocket의 경우 따로 리스트를 두고 socket을 담거나 제거하여 관리한다. Socket.io의 경우 server.sockets로 서버에 연결된 모든 소켓들을 불러올 수 있다. 그리고 server.sockets.adapter 를 이용하여 연결된 소켓 정보나 현재 실행된 이벤트정보를 알 수 있다.

Socket ids & room
Socket events

1-3. Room 관리

WebSocket의 경우 Room이라는 개념이 없고 Socket들에게 일일히 전송하는 걸로 구현할 수 있지만, Socket.io에서는 Room이라는 개념이 있어 아래와 같이 해당 Room에 연결된 소켓들에게만 전송하는게 가능하다.

    socket.on("enter_room", (roomName, done) => {
        socket.join(roomName);
        done();
        socket.to(roomName).emit("welcome", socket.nickname, countRoom(roomName));
        wsServer.sockets.emit("room_change", publicRooms());
    });

join()함수를 이용해 socket이 진입한 room을 설정할 수 있으며. socket.to(Room)으로 해당 룸에 함수를 연결하여 실행하는 것이 가능하다. 그리고 server에 연결된 모든 socket들에도 메시지를 보낼 수 있다.

반응형

1-4. Callback 함수

function showRoom(){
    welcome.hidden = true;
    room.hidden = false;
    const h3 = room.querySelector("h3");
    h3.innerText = `Room ${roomName}`;
}

socket.emit("enter_room", input.value, showRoom);

socket.io는 메시지 전송 후 서버쪽에서 callback함수를 실행시킬 수 있다. 메시지 전송 후 emit()을 이용하여 또다른 함수를 발생시킬 수도 있지만, 관련된 callback함수를 넣어 실행시켜주는 것이 깔끔하다. 메시지 전송에 대한 결과로 view가 변경되어야할 경우 유용하다.


2. Socket에 Nickname 정보 넣기

// Socket에 Nickname 정보로 "ananymous"로 값 초기화
socket["nickname"] = "ananymous";
// Socket Nickname 정보 변경
socket.on("nickname", (nickname) => {socket["nickname"] = nickname;});
// Socket Nickname 정보 사용
socket.on("new_message", (msg, room, done)=> {       
        socket.to(room).emit("new_message", `${socket.nickname} : ${msg}`);       
        done();   
});

Socket.io는 socket에 저장하고 싶은 정보를 저장하고 해당 값을 가져다 쓸 수 있다.


3. View Engine - Pug

view engine은 pug를 사용하여 쉽고 간결하게 구현할 수 있다.

import http from "http";
import { Server } from "socket.io";
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

4. Socket.io admin-ui 사용

onst { createServer } = require("http");
const { Server } = require("socket.io");
const { instrument } = require("@socket.io/admin-ui");

const httpServer = createServer();

const io = new Server(httpServer, {
  cors: {
    origin: ["https://admin.socket.io"],
    credentials: true
  }
});

instrument(io, {
  auth: false
});

instrument를 설정해주고 server의 origin을 admin.socke.io 경로로 설정해주면 Socket.io의 관리자 페이지를 사용할 수 있다.

admin-ui connection설정

Connection을 현재 listen하고 있는 서버 주소로 설정해준다. 그리고 연결을 누르면 아래 화면과 같이 대쉬보드가 나타나며 Socket/Room/Clients/Event/Server 들의 정보를 알 수 있다. 서버 여러대를 연결하여 구현하여도 이와 같이 관리자 페이지로 관리하기 쉽다.

socket.io.admin-ui 화면

만약 socket.io.admin-ui 설치가 안된다면 아래 글을 참고하자.

2022.08.19 - [개발 Study/Node, js, react] - [Error] npm i @socket.io/admin-ui 설치 에러 해결

 

[Error] npm i @socket.io/admin-ui 설치 에러 해결

npm i @socket.io/admin-ui 에러 처리 socket.io 관련 모든 페이지를 뒤졌지만 아래처럼 입력해서 설치하라고만 나오고 에러에 대한 설명이라던가 에러가 났다고 나오는 글들이 없어 이렇게 남김. 자꾸 '@'

chuun92.tistory.com

 


WebRTC를 이용해서 실시간 스트리밍으로 화상채팅 하는건 다음 글에 포스팅할 예정이다.

반응형

댓글