(코드용) 줌 클론코딩 1~2장
2021. 11. 2. 21:15ㆍ작업/Node
server.js 2장최종
import http from "http";
import express from "express";
import SocketIO from "socket.io";
//모듈 import
const app = express();
//set
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
//static
app.use("/public", express.static(__dirname + "/public"));
//라우터
app.get("/", (req, res) => res.render("home")); //페이지 렌더링
app.get("/*", (req, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on http://localhost:3000`);
const httpserver = http.createServer(app);
const wsServer = SocketIO(httpserver);
function publicRooms(){
const sids = wsServer.sockets.adapter.sids;
const rooms = wsServer.sockets.adapter.rooms;
//위 두개를 더 깔끔히 쓰면 const {sockets: {adapter: {sids, rooms }}} = wsServer;
const publicRooms = [];
rooms.forEach((_,key) => {
if (sids.get(key)===undefined) { //sids 의 키가 undefined면 public room임
publicRooms.push(key);
}
});
return publicRooms;
}
function countRoom(roomName){
return wsServer.sockets.adapter.rooms.get(roomName)?.size // 찾을 수도 있고 아닐수도 -> ?
}
//socket.on("이벤트",arg,콜백함수)
wsServer.on("connection",(socket) => {
socket["nickname"]="Anonymus";
socket.onAny((event)=>{
console.log(`Socket Event: ${event}`);
});
socket.on("enter_room", (roomName, done)=>{
socket.join(roomName);
done();
socket.to(roomName).emit("welcome", socket.nickname, countRoom(roomName)); //하나의 socket에만 메세지 보냄
wsServer.sockets.emit("room_change",publicRooms()); //모든 socket에 메세지 보냄
});
socket.on("disconnecting", () => {
socket.rooms.forEach(room => socket.to(room).emit("bye", socket.nickname, countRoom(room) -1));
}) //떠나기 직전
socket.on("disconnect", () => {
wsServer.sockets.emit("room_change",publicRooms());
})
socket.on("new_message",(msg, room, done) => {
socket.to(room).emit("new_message", `${socket.nickname}: ${msg}`);
done();
})
socket.on("nickname", (nickname) => socket["nickname"]=nickname)
});
// const sockets=[]; //[firefox, chrome] firefox랑 연결할 때, chrome랑 연결할 떄
// //wss.on(이벤트,콜백함수)
// wss.on('connection', (socket) => {
// sockets.push(socket);
// socket['nickname']='Anonymous'; //처음에 닉네임 익명으로 초기화
// console.log("Connected to Browser ✅")
// socket.on("close", ()=>{ //listener
// console.log("Disconnected from the Browser ❌");
// })
// socket.on('message', msg => {
// const message = JSON.parse(msg); // JSON.parse
// switch(message.type){
// case "new_message":
// sockets.forEach((aSocket)=> {
// aSocket.send(`${socket.nickname}:${message.payload}`);
// //모두에게 해당 메세지 send
// })
// case "nickname":
// socket["nickname"]=message.payload;
// //nickname입력 시 nickname 저장
// }
// });
// });
//app.listen(3000,handleListen);
httpserver.listen(3000, handleListen);
app.js 2장최종
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("#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);
input.value='';
}
function showRoom() {
welcome.hidden=true; //room 입장은 숨기고
room.hidden = false; //메세지 입력은 생기게
const h3 = room.querySelector("h3");
h3.innerText = `${roomName} Room`;
const msgForm = room.querySelector('#msg'); //메세지 만드는 폼
const nameForm = room.querySelector('#name'); //닉네임 만드는 폼
msgForm.addEventListener("submit",handleMessageSubmit);
nameForm.addEventListener("submit",handleNicknameSubmit);
}
//중요! emit과 on은 event명이 같아야 한다.
function handleRoomSubmit (event) {
event.preventDefault();
const input = form.querySelector("input");
//socket.emit("아무 이벤트",argument,콜백함수)
socket.emit("enter_room",input.value, showRoom);
roomName=input.value; //방 이름 입력값으로 설정
input.value=""
}
form.addEventListener("submit", handleRoomSubmit);
//방에 참가하면 누군가 참가했습니다 반가워
socket.on("welcome", (user, newCount) => {
const h3 = room.querySelector("h3");
h3.innerText = `${roomName} Room (${newCount})`;
addMessage(`${user} Arrived!`);
});
//방에서 누가 나갔을 때
socket.on("bye", (left, newCount) => {
const h3 = room.querySelector("h3");
h3.innerText = `${roomName} Room (${newCount})`;
addMessage(`${left} Left TT`);
});
//누군가 보낸 메세지 보이기
socket.on("new_message", addMessage);
socket.on("room_change",(rooms) => {
const roomList = welcome.querySelector("ul");
roomList.innerHTML =""; //항상 비워주기
if(rooms.length ===0) {
return;
}
rooms.forEach(room => { //rooms 리스트에 넣은 요소마다 li 태그 생성
const li = document.createElement('li');
li.innerText = room;
roomList.append(li);
})
});
home.pug 2장최종
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
h4 Open Rooms:
ul
div#room
h3
ul
form#name
input(placeholder="nickname", required, type="text")
button Save
form#msg
input(placeholder="message", required, type="text")
button Send
script(src="/socket.io/socket.io.js")
script(src="/public/js/app.js")
'작업 > Node' 카테고리의 다른 글
21.10.30 노드교과서 Node.js 다뤄보기 (0) | 2021.11.01 |
---|---|
21.10.27 Node js Express의 효용 (0) | 2021.10.27 |
21.10.27 Node.js 한 시간 만에 끝내기 (0) | 2021.10.27 |