#2.4 Rooms
Room 이란? : 서로 소통 가능한 socket 들의 그룹
모든 websocket이 서로 대화할 필요는 없다. 그저 room 안에 몇개의 websocket 들끼리만 대화하면 된다.
꼭 Chat room 뿐 아니라 websocket 들은 그룹으로 묶일 필요가 있는 것이다.
예를 들어 배달 앱이라고 하더라도, 배달 기사의 위치를 나한테 알려주기 위해서는
배달기사 <-> 나 와의 socket 이 room 안에 따로 있어야하는 것이다.
socketIO는 join 메소드를 통해 room 기능을 제공하고 있다.
참고)socket.id
https://socket.io/docs/v4/server-api/#socketid
Server API | Socket.IO
Server
socket.io
참고) socket. onAny : 임의의 이벤트에서든 실행됨으로써 모든 socket 에 대한 이벤트를 모니터링 할 수 있음
https://socket.io/docs/v4/server-api/#socketonanycallback
Server API | Socket.IO
Server
socket.io
//server.js
line 23~30 을 수정해주었다.
- socket이 어느 방에 있는지 알기 -> socket.rooms
- 방에 들어가기 -> socket.join(room1) , socket.join(room1, room2) -> 동시에 여러 방 접속 가능
- socket 구분 : socket.id
import http from "http"; import SocketIO from "socket.io" import WebSocket from "ws"; import express from "express"; const app = express(); //set the view app.set("view engine", "pug"); app.set("views", __dirname + "/views"); app.use("/public", express.static(__dirname + "/public")); //user가 public 으로 이동하면 __dirname+/public 폴더를 보여주는 것. app.get("/", (req, res) => res.render("home"));//render app.get("/*", (req, res) => res.redirect("/")); const handleListen = () => console.log('Listening on http://localhost:3000'); //app.listen(3000, handleListen); //http의 서버 const httpServer = http.createServer(app); //app은 requestListener 의 경로. express application으로부터 서버 생성. const wsServer = SocketIO(httpServer); wsServer.on("connection", (socket) => { socket.onAny((event) => { //socket 에 있는 모든 이벤트 모니터링 가능 console.log(`Socket Event: ${event}`); }); socket.on("enter_room", (roomName, done) => { console.log(socket.id); console.log(socket.rooms); // Set { <socket.id> socket.join(roomName); console.log(socket.rooms); // Set { <socket.id>, "room1" } setTimeout(() => { done(); }, 15000); }); }); //websocket 서버 //const wss = new WebSocket.Server({ httpServer }); // function handleConnection(socket) { // console.log(socket) // } // const sockets = []; // wss.on("connection", (socket) => { // sockets.push(socket); // socket["nickname"] = "Anon"; //처음엔 익명으로 설정 // console.log("Connected to Browser ✅"); // socket.on("close", () => { // console.log("Disconnected from the Browser ❌"); // }); // socket.on("message", (msg) => { // const message = JSON.parse(msg); //string -> Object // //console.log(message, message.toString('utf-8')); // switch(message.type){ // case "new_message" : // //sockets.forEach((aSocket) => aSocket.send(message.payload.toString('utf-8'))); //채팅 메세지만 출력하기 위해 이것만 브라우저에 보냄 // sockets.forEach((aSocket) => aSocket.send(`${socket.nickname}: ${message.payload}`)); //누가 보냈는지, 뭘 보냈는지 // case "nickname" : // //console.log(message.payload.toString('utf-8')); // socket["nickname"] = message.payload; // } // }); // }); httpServer.listen(3000, handleListen);
코드 수정 후 room name 을 브라우저에서 입력했더니 backend에서 아래와 같이 확인할 수 있었다.
qay~ 부분이 socket.id 이며,
Set(1) 은 모든 socket 은 처음에 private room 을 한개씩 가지고 있기 때문에 RoomName 이 설정되지 않은 상태의 room 이며
Set(2)는 사용자가 브라우저에 myroom~이라고 RoomName을 지정했을 때의 Room 이다.

참고)
- 방 떠나기 : socket.leave()
- 방 전체에 메세지 broadcasting : socket.to("room1")
io.on("connection", (socket) => { // to one room socket.to("others").emit("an event", { some: "data" }); // to multiple rooms socket.to("room1").to("room2").emit("hello"); // or with an array socket.to(["room1", "room2"]).emit("hello"); // a private message to another socket socket.to(/* another socket id */).emit("hey"); // WARNING: `socket.to(socket.id).emit()` will NOT work // Please use `io.to(socket.id).emit()` instead. });
위 기능들을 활용해서, 방에 참가했을 때 방 안의 모든 사람들에게 참여했음을 알리는 메세지를 전송해보자.
먼저 HTML 을 수정한다. (div room 추가)
doctype html html(lang="en") head meta(charset="UTF-8") meta(http-equiv="X-UA-Compatible", content="IE=edge") meta(name="viewport", content="width=device-width, initial-scale=1.0") title Noom link(rel="stylesheet", href="https://unpkg.com/mvp.css") body header h1 Noom main div#welcome form input(placeholder="room name", required, type = "text") button Enter Room div#room ul form input(placeholder="message", required, type = "text") button Send script(src="/socket.io/socket.io.js") script(src="/public/js/app.js")
이제 frontend 를 수정한다.
위에서 생성한 div#room은 처음에는 보이지 않아야 한다. 처음에는 div#welcome 만 보이고,
roomname 을 입력한 뒤에 방에 들어가면 메세지를 입력할 수 있어야 하기 때문이다.
room Element를 가져오고, (line 5)
showRoom 메소드를 생성하여 front에서 showRoom이 실행되면 즉 roomName 이 입력되면
그 입력된 값을 back->front 로 넘겨줄 때 이 메소드를 실행하여 welcome 은 숨기고 room 은 보여지게 된다. (line 9~12)
//app.js
const socket = io(); const welcome = document.getElementById("welcome"); const form = welcome.querySelector("form"); const room = document.getElementById("room"); room.hidden = true; function showRoom(){ welcome.hidden = true; room.hidden = false; } function handleRoomSubmit(event){ event.preventDefault(); const input = form.querySelector("input"); socket.emit("enter_room", input.value, showRoom); input.value = ""; } form.addEventListener("submit", handleRoomSubmit);
이제 참가한 room에 누가 참가했는지를 알려주자.
home.pug 에 h3 를 추가하자.
div#room h3 ul form input(placeholder="message", required, type = "text") button Send
그 후 app.js 에
roomName 변수를 생성하고 (line 8)
handleRoomSubmit 에 roomName 을 넣어주고 (line21)
showRoom에서 h3 변수를 생성한 뒤 html 의 h3 아이템을 받아와서 내용을 roomName으로 바꿔준다. (line 14-15)
const socket = io(); const welcome = document.getElementById("welcome"); const form = welcome.querySelector("form"); const room = document.getElementById("room"); room.hidden = true; let roomName; function showRoom(){ welcome.hidden = true; room.hidden = false; const h3 = room.querySelector("h3"); h3.innerText = `Room ${roomName}`; } function handleRoomSubmit(event){ event.preventDefault(); const input = form.querySelector("input"); socket.emit("enter_room", input.value, showRoom); roomName = input.value; input.value = ""; } form.addEventListener("submit", handleRoomSubmit);
실행 후 방 이름을 입력하면
해당 방에 들어왔다는 의미로 h3 헤드라인이 출력된다.

다음 편에서는 방에 들어왔을 때 방의 모든 사람들에게 인사를 하는 기능을 추가해보자.
'JavaScript' 카테고리의 다른 글
노마드코더 줌 클론코딩 - #2.6 Room Notifications (0) | 2022.12.11 |
---|---|
노마드코더 줌 클론코딩 - #2.5 Room Message (0) | 2022.12.11 |
노마드코더 줌 클론코딩 - #2.2 SocketIO is Amazing (0) | 2022.12.11 |
노마드코더 줌 클론코딩 - #2.0 SocketIO vs WebSockets / #2.1 Installing SocketIO (0) | 2022.12.11 |
노마드코더 줌 클론코딩 - #1.9 Conclusions (0) | 2022.12.11 |