src/server.js
=>결과
- 방에 입장하면 방 입력하는 폼을 숨기고 채팅 폼을 보여주도록
- 방에 입장했을때 방 이름을 보여주도록
div#room
h3
ul
form
input(placeholder="message", required, type="text")
button Send
const room = document.getElementById("room");
// 방에 입장 전엔 숨겨주기
room.hidden = true;
// 입장 전엔 roomName empty
let roomName;
app.js
//app.js
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.send와 같은 역할
socket.emit("enter_room", input.value, showRoom);
roomName = input.value;
input.value = "";
}
server.js
//server.js
socket.on("enter_room", (roomName, done) => {
socket.join(roomName);
//showRoom()
done();
});
들어간 방에 있는 나를 제외한 모든 사람들에게 입장했다는 메시지를 보내고 싶음!
socket.on("enter_room", (roomName, done) => {
socket.join(roomName);
done();
// 입장메시지 보내기
socket.to(roomName).emit("welcome");
});
function addMessage(message) {
const ul = room.querySelector("ul");
const li = document.createElement("li");
li.innerText = message;
ul.appendChild(li);
}
//welcome이벤트를 받으면 함수실행
socket.on("welcome", () => {
// 나를 제외한 모든 이에게
addMessage("Someone Joined!");
});
방을 떠날때 메시지를 주고 나가고 싶음 => disconnecting
// 연결 끊을때 - 모든 방에 bye 이벤트 보내기
socket.on("disconnecting", () => {
socket.rooms.forEach((room) => socket.to(room).emit("bye"));
});
socket.on("bye", () => {
addMessage("Someone Left ㅠㅠ");
});
서로에게 메시지를 보내고 싶음. 내가 보낼 때는 you:를 붙여서 보여주고싶음!
function showRoom() {
welcome.hidden = true;
room.hidden = false;
// 방 이름 보여주기
const h3 = room.querySelector("h3");
h3.innerText = `Room ${roomName}`;
// submit이벤트가 발생하면 handleMessageSubmit실행
const form = room.querySelector("form");
form.addEventListener("submit", handleMessageSubmit);
}
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 = "";
}
socket.on("new_message", (msg, room, done) => {
socket.to(room).emit("new_message", msg);
done();
});
socket.on("new_message", addMessage);
nickname입력폼을 추가해야해서 id값도 넣어주고 eventListener도 추가해주고,
form#name
input(placeholder="nickname", required, type="text")
button Save
form#msg
input(placeholder="message", required, type="text")
button Send
function handleMessageSubmit(event) {
event.preventDefault();
const input = room.querySelector("#msg input");
const value = input.value;
socket.emit("new_message", input.value, roomName, () => {
addMessage(`You: ${value}`);
});
input.value = "";
}
function handleNicknameSubmit(event) {
event.preventDefault();
const input = room.querySelector("#name input");
socket.emit("nickname", input.value);
}
function showRoom() {
welcome.hidden = true;
room.hidden = false;
// 방 이름 보여주기
const h3 = room.querySelector("h3");
h3.innerText = `Room ${roomName}`;
const msgForm = room.querySelector("#msg");
const nameForm = room.querySelector("#name");
msgForm.addEventListener("submit", handleMessageSubmit);
nameForm.addEventListener("submit", handleNicknameSubmit);
}
server.js
wsServer.on("connection", (socket) => {
socket["nickname"] = "unknown";
// onAny : middleware같은거, 어떤 event에서든지 console.log가능
socket.onAny((event) => {
console.log(`Socket Event:${event}`);
});
//socket.on("message")사용안함. 우리가 원하는 이벤트로 사용가능
socket.on("enter_room", (roomName, done) => {
socket.join(roomName);
//showRoom()호출
done();
// 입장메시지 보내기(welcome이벤트를 나를 제외한 방의 모든 사람들에게 emit)
socket.to(roomName).emit("welcome", socket.nickname);
});
// 연결 끊을때 - 모든 방에 bye 이벤트 보내기
socket.on("disconnecting", () => {
socket.rooms.forEach((room) =>
socket.to(room).emit("bye", socket.nickname)
);
});
socket.on("new_message", (msg, room, done) => {
socket.to(room).emit("new_message", `${socket.nickname}: ${msg}`);
done();
});
socket.on("nickname", (nickname) => (socket["nickname"] = nickname));
});
app.js
socket.on("welcome", (user) => {
addMessage(`${user} Joined!`);
});
socket.on("bye", (left) => {
addMessage(`${left} Left ㅠㅠ`);
});
wsServer.socketJoin("announcement");
adapter : 다른 서버들 사이에 실시간 어플리케이션을 동기화
console.log(wsServer.sockets.adapter);
server.js
function publicRooms() {
const sids = wsServer.sockets.adapter.sids;
const rooms = wsServer.sockets.adapter.rooms;
const publicRooms = [];
rooms.forEach((_, key) => {
if (sids.get(key) === undefined) {
publicRooms.push(key);
}
});
return publicRooms;
}
이렇게도 가능 =>
server.sockets.emit
을 사용해서 message(방 목록)를 모두에게 보내줄 것
server.js
socket.on("enter_room", (roomName, done) => {
socket.join(roomName);
//showRoom()호출
done();
// 입장메시지 보내기(welcome이벤트를 나를 제외한 방의 모든 사람들에게 emit)
socket.to(roomName).emit("welcome", socket.nickname); // 하나의 소켓에
wsServer.sockets.emit("room_change", publicRooms()); // 모든 소켓에
});
socket.on("disconnect", () => {
wsServer.sockets.emit("room_change", publicRooms());
});
home.pug
div#welcome
form
input(placeholder="room name", required, type="text")
button Enter Room
h4 Open Rooms:
ul
app.js
socket.on("room_change", (rooms) => {
const roomList = welcome.querySelector("ul");
//방목록을 항상 비워주기! 그래야 전에 것이 또 추가가 안됨!
roomList.innerHTML = "";
if (rooms.length === 0) {
return;
}
rooms.forEach((room) => {
const li = document.createElement("li");
li.innerText = room;
roomList.append(li);
});
});
+두 개가 같음 =>
set.size
를 이용해서 유저 수를 가져올것
server.js
// count room user
function countRoom(roomName) {
// roomName을 찾지 않을 수도 있어서 ?
return wsServer.sockets.adapter.rooms.get(roomName)?.size;
}
...
socket.on("enter_room", (roomName, done) => {
socket.join(roomName);
//showRoom()호출
done();
// 입장메시지 보내기(welcome이벤트를 나를 제외한 방의 모든 사람들에게 emit)
socket.to(roomName).emit("welcome", socket.nickname, countRoom(roomName)); // 하나의 소켓에
wsServer.sockets.emit("room_change", publicRooms()); // 모든 소켓에
});
// 연결 끊을때 - 모든 방에 bye 이벤트 보내기
socket.on("disconnecting", () => {
socket.rooms.forEach((room) =>
socket.to(room).emit("bye", socket.nickname, countRoom(room) - 1) // 아직 확실하게 떠나기 전이라서
);
});
app.js
socket.on("welcome", (user, newCount) => {
const h3 = room.querySelector("h3");
h3.innerText = `Room ${roomName} (${newCount})`;
addMessage(`${user} Joined!`);
});
socket.on("bye", (left, newCount) => {
const h3 = room.querySelector("h3");
h3.innerText = `Room ${roomName} (${newCount})`;
addMessage(`${left} Left ㅠㅠ`);
});