#2.6 Room Notifications
이제 사용자가 방을 떠날 때 이를 알리는 기능을 구현해보자.
여기서 disconnecting 과 disconnected 를 구별해야한다.
disconnecting 은 완전히 disconnected 되기 전의 상태이기 때문에 메세지를 보낼 수 있는 것이다.
socket.rooms 를 하면 아래와 같이 Set 을 의미한다. Set 이기 때문에 forEach 즉, 반복이 가능하다.
qay... 는 room.id 이며 myroom~ 은 roomName 이다.
그리고 server.js 에 아래의 line 31~33 과 같이 disconnecting 이벤트에 대해 코드를 추가해준다.
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) => {
socket.join(roomName);
done();
socket.to(roomName).emit("welcome"); //모든 사람에게 welcome 이벤트 Emit
});
socket.on("disconnecting", () => {
socket.rooms.forEach(room => socket.to(room).emit("bye"));
})
});
httpServer.listen(3000, handleListen);
app.js 에도 앞서 했던 welcome 과 동일한 방식으로 bye 도 추가해준다.
socket.on("bye", () => {
addMessage("Someone Left!");
});
방에 들어갔다가 나갔음을 알 수 있다.
이제 메세지를 보내보자.
room 안에 있는 message 를 from 에서 찾아서 -> addEventListener 를 추가한뒤 -> new_message event 를 보내면 된다.
먼저 방에 들어왔음을 보여주는 showRoom 메서드 안에서 from 을 찾아보자. (line 32~33)
그 후 line 17~25 와 같이 handleMessageSubmit 을 작성한다. 이 메소드는 우리가 브라우저에서 입력한 메세지 내용을 backend로 전송해주는 역할을 한다. 전송 시 roomName도 함께 인자로 보내줘서 backend 가 어디 room 으로 보낼지 식별 가능하도록 한다.
handleMessageSubmit 에서 input.value 를 초기화 시켜줄때 주의해야한다.
왜냐하면 emit 을 통해 backend 로 보내고 다시 메세지를 front 로 받는 과정에서
input.value = "" 를 통해 초기화 되어버리기 때문에 브라우저에 출력이 되지 않게 되는 문제가 있기 때문이다.
그렇기 때문에 value 라는 변수 선언을 통해 값을 저장해놓고 (line20)
line22 에서 그 저장된 값을 쓰도록 함으로써 line 24에 영향을 받지 않도록 한다.
//app.js
const socket = io();
const welcome = document.getElementById("welcome");
const form = welcome.querySelector("form");
const room = document.getElementById("room");
room.hidden = true;
let roomName;
function addMessage(message){
const ul = room.querySelector("ul");
const li = document.createElement("li");
li.innerText = message;
ul.appendChild(li);
}
function handleMessageSubmit(event){
event.preventDefault();
const input = room.querySelector("input");
const value = input.value;
socket.emit("new_message", input.value, roomName, () => { //백엔드에 입력한 메세지 전송
addMessage(`You: ${value}`); //대화창에 메세지 출력
});
input.value = "";
}
function showRoom(){
welcome.hidden = true;
room.hidden = false;
const h3 = room.querySelector("h3");
h3.innerText = `Room ${roomName}`;
const form = room.querySelector("form");
form.addEventListener("submit", handleMessageSubmit);
}
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);
socket.on("welcome", () => {
addMessage("Someone Joined!");
});
socket.on("bye", () => {
addMessage("Someone Left!");
});
socket.on("new_message", (addMessage));
// = socket.on("new_message", (msg) => {addMessage});
front 에서 보낸 메세지를 이제 backend 에서 받아보자.
(line 34~37 추가)
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) => {
socket.join(roomName);
done();
socket.to(roomName).emit("welcome"); //모든 사람에게 welcome 이벤트 Emit
});
socket.on("disconnecting", () => {
socket.rooms.forEach(room => socket.to(room).emit("bye"));
})
socket.on("new_message" , (msg, room, done) => {
socket.to(room).emit("new_message", msg);
done();
})
});
httpServer.listen(3000, handleListen);
그 후 backend 에서 front 로 보내는 socket.to(room).emit("new_message", msg) 부분을
front 에 출력하기 위해 아래와 같이 함수를 추가해준다.
socket.on("new_message", (addMessage));
실행해보자.
You 를 통해 어디서 보낸 메세지인지 식별이 가능해졌다.
'JavaScript' 카테고리의 다른 글
노마드코더 줌 클론코딩 - #3.1 Call Controls (0) | 2023.01.22 |
---|---|
노마드코더 줌 클론코딩 - #3.0 User Video (0) | 2023.01.08 |
노마드코더 줌 클론코딩 - #2.5 Room Message (0) | 2022.12.11 |
노마드코더 줌 클론코딩 - #2.4 Rooms (0) | 2022.12.11 |
노마드코더 줌 클론코딩 - #2.2 SocketIO is Amazing (0) | 2022.12.11 |