728x90

#2.7 NickNames

Line 20~22를 추가한다. 

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
                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")

 

form 을 추가했으니 eventListener 가 필요하다. 이제 app.js를 수정해주자.

handleMessageSubmit(), handleNicknamesSubmit(), showRoom() 메서드를 수정해주자. 

const socket = io();

const welcome = document.getElementById("welcome");
const msgForm = welcome.querySelector("msgForm");
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 handleNicknamesSubmit(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", handleNickNamesSubmit);
}

function handleRoomSubmit(event){
    event.preventDefault();
    const input = msgForm.querySelector("input");
    socket.emit("enter_room", input.value, showRoom);
    roomName = input.value;
    input.value = "";
}
msgForm.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});

function 안에서는 각각의 form의 id에 기반해서 input 값을 가져온다. 

 

 

이제 백앤드 부분을 수정해주자. (server.js)

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["nickname"] = "Anon";
    socket.onAny((event) => {   //socket 에 있는 모든 이벤트 모니터링 가능
        console.log(`Socket Event: ${event}`);
    });
    socket.on("enter_room", (roomName, done) => {
        socket.join(roomName);
        done();
        socket.to(roomName).emit("welcome", socket.nickname);    //모든 사람에게 welcome 이벤트 Emit
    });
    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));
});

httpServer.listen(3000, handleListen);

Line 39 : nickname 이벤트가 발생을 하면 nickname을 가져와서 socket 에 저장한다.

 

nickname 기능을 추가했으니 해당 기능을 화면에 표시하기 위해 app.js 를 추가로 수정해준다.

누군가 채팅방에 접속하고 나갔을 때 nickname 을 표시하기 위해 welcome, bye 부분에 추가해준다.

const socket = io();

const welcome = document.getElementById("welcome");
const msgForm = welcome.querySelector("msgForm");
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 handleNicknamesSubmit(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", handleNickNamesSubmit);
}

function handleRoomSubmit(event){
    event.preventDefault();
    const input = msgForm.querySelector("input");
    socket.emit("enter_room", input.value, showRoom);
    roomName = input.value;
    input.value = "";
}
msgForm.addEventListener("submit", handleRoomSubmit);

socket.on("welcome", (user) => {
    addMessage(`${user} arrived!`);  
}); 

socket.on("bye", (left) => {
    addMessage(`${left} left ㅠㅠ`);  
});

socket.on("new_message", (addMessage)); 
// = socket.on("new_message", (msg) => {addMessage});$

 

이제 실행해보자. 

 

123 방에 접속하면 처음 nickname 을 지정하지 않았을 때는 Anon 이 채팅방에 접속했다고 출력되며,

nickname 을 각자 지정하고 메세지를 전송하면 아래와 같이 메세지 앞에 nickname 이 붙어서 출력된다. 

그리고 user2 (좌측)가 창을 닫으면 user1 (우측) 창에 user2 left 라는 텍스트가 출력되는 것도 확인할 수 있다. 

 

 

Challenge

채팅 방에 입장하기 전에 방이름과 닉네임을 먼저 물어보는 코드를 작성해보자.

(결과)

//home.pug

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#nickname-and-room-name
                    input#nickname(placeholder="nickname", required, type = "text")
                    input#room-name(placeholder="room name", required, type = "text")
                    button Enter Room
                
            div#room
                h3
                ul
                form#msg
                    input(placeholder="message", required, type = "text")
                    button Send 
        script(src="/socket.io/socket.io.js")    
        script(src="/public/js/app.js")

 

//app.js

const socket = io();
 
const welcome = document.getElementById("welcome");
//const form = welcome.querySelector("form");
const form = document.getElementById("nickname-and-room-name");
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); 
// }
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);
}
 
//function handleRoomSubmit(event){
function handleNicknameAndRoomSubmit(){
    event.preventDefault();
    // const input = form.querySelector("input");
    // socket.emit("enter_room", input.value, showRoom);
    // roomName = input.value;
    // input.value = "";

    const submittedNickname = document.getElementById("nickname");
    const submittedRoomName = document.getElementById("room-name")
    socket.emit("nickname", submittedNickname.value);
    socket.emit("roomName", submittedRoomName.value);
    socket.emit("enter_room", submittedNickname.value, submittedRoomName.value, showRoom);
    roomName = submittedRoomName.value;

}
function handleFirstNickname(event){
    event.preventDefault();
    const input = firstNickname.querySelector("input");
    socket.emit("enter_first_Nickname", input.value);
    input.value="";
}



//form.addEventListener("submit", handleRoomSubmit);
form.addEventListener("submit", handleNicknameAndRoomSubmit);

socket.on("welcome", (user) => {
    addMessage(`${user} arrived!`);  
}); 
 
socket.on("bye", (left) => {
    addMessage(`${left} left ㅠㅠ`);  
});
 
socket.on("new_message", (addMessage)); 
// = socket.on("new_message", (msg) => {addMessage});

 

//server.js

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["nickname"] = "Anon";
    socket["roomName"] = "";
    socket.onAny((event) => {   //socket 에 있는 모든 이벤트 모니터링 가능
        console.log(wsServer.sockets.adpater);
        console.log(`Socket Event: ${event}`);
    });
    socket.on("enter_room", (nickname, roomName, done) => {
        socket.join(roomName);
        done();
        socket.to(roomName).emit("welcome", socket.nickname);    //모든 사람에게 welcome 이벤트 Emit
    });
    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));
    socket.on("roomName", roomName => (socket["roomName"] = roomName));
});
 
httpServer.listen(3000, handleListen);

 

728x90

+ Recent posts