(코드용) 줌 클론코딩 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