frontSocket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
main
form#nick
input(type="text", placeholder="Choose a nickname", required)
button Save
ul
form#message
input(type="text", placeholder="Write a message", required)
button Send Message
script(src="/public/js/app.js")
const nickForm = document.querySelector("#nick");
const messageForm = document.querySelector("#message");
nickForm.addEventListener("submit",handleNickSubmit);
-> frontend에서 nickform과 messageform 둘 다에서 message를 보내는데, backend는 이 메시지를 구분하지 못함. 그래서 우리는 {type:"message", message:"input.value"} 와 같이 type으로 구분할 수 있게 JSON형태로 보내줄 것임.
function makeMessage(type, payload){
const msg = {type, payload};
return JSON.stringify(msg);
}; //JSON형태로 {type:"message", payload:"input.value"} 이런 식으로 보내주는 것.
function handleSubmit(event){
event.preventDefault();
const input = messageForm.querySelector("input");
frontSocket.send(makeMessage("new_message", input.value));//chat message를 JSON형태로 object로 backend에 보내기
input.value="";
};
function handleNickSubmit(event){
event.preventDefault();
const input = nickForm.querySelector("input");
frontSocket.send(makeMessage("nickname",input.value));//niname message를 JSON형태로 object로 backend에 보내기
input.value="";
};
wss.on("connection",(backSocket) => {
sockets.push(backSocket);
backSocket["nickname"] = "Anonymous"; //아직 닉네임 정하지 않은 사람.
console.log("Connected to Browser ✅");
backSocket.on("close", () => console.log("Disconnected to the Brower ❌"));
backSocket.on("message",(msg) =>{
const message = JSON.parse(msg);
switch (message.type){
case "new_message":
sockets.forEach((aSocket) => {aSocket.send(`${backSocket.nickname}: ${(message.payload).toString()}`)});
case "nickname":
backSocket["nickname"] = message.payload;//backSocket에 닉네임 넣어주기
};
});
});

const messageList = document.querySelector("ul");
const nickForm = document.querySelector("#nick");
const messageForm = document.querySelector("#message");
const frontSocket = new WebSocket(`ws://${window.location.host}`);//frontend의 socket등록.
function makeMessage(type, payload){
const msg = {type, payload};
return JSON.stringify(msg);
}; //JSON형태로 {type:"message", payload:"input.value"} 이런 식으로 보내주는 것.
frontSocket.addEventListener("open",() => {
console.log("Connected to Server ✅");
});
frontSocket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
frontSocket.addEventListener("close",() => {
console.log("Disconnected to Server ❌");
});
function handleSubmit(event){
event.preventDefault();
const input = messageForm.querySelector("input");
frontSocket.send(makeMessage("new_message", input.value));
input.value="";
};
function handleNickSubmit(event){
event.preventDefault();
const input = nickForm.querySelector("input");
frontSocket.send(makeMessage("nickname",input.value));
input.value="";
};
messageForm.addEventListener("submit",handleSubmit);
nickForm.addEventListener("submit",handleNickSubmit);
import http from "http";
import WebSocket from "ws";
import express from "express";
import { Socket } from "dgram";
const app = express();
app.set("view engine", "pug");
app.set("views", __dirname + "/views"); // 현재 실행중인 폴더 경로 = process.cwd()와 같다고 볼 수 있음. __dirname : returns the directory name of the directory containing the JavaScript source code file// process.cwd(): returns the current working directory, 즉, node명령을 호출한 디렉토리입니다.
app.use("/public", express.static(__dirname + "/public"));//이미지, CSS 파일 및 JavaScript 파일과 같은 정적 파일을 제공하려면 Express의 기본 제공 미들웨어 함수인 express.static을 사용하십시오. -> app.use('/static', express.static(__dirname + '/public')); 이제 /static 경로 접두부를 통해 public 디렉토리에 포함된 파일을 로드할 수 있습니다.// 정적 파일이란, 직접 값에 변화를 주지 않는 이상 변하지 않는 파일을 의미합니다. 예를 들면, image, css 파일, js 파일 등을 의미합니다. -> static: 정적 파일만을 제공////보안상 유저는 서버 내 모든 폴더를 전부 들여다볼 수 없음(보안상의 이유 때문에) 그래서 유저가 볼 수 있는 폴더를 따로 지정해야댐. 즉, 이건 Front-end폴더임.
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));// -> catchall : 어떤 url을 가든 "/"로 돌아오게 만들어 home.pug만 볼 수 있도록 하기. 이번 프로젝트에서는 하나의 url만 사용할 것이기 때문에 이렇게 처리해줌.
const handleListen = () => console.log(`Listening on http://localhost:3000, ws://localhost:3000`);
const server = http.createServer(app);//server에 접근하도록 만들어 준 것임.
const wss = new WebSocket.Server({ server });//ws 서버 만들기, wss가 서버가 된 것이라 보면 편함.
const sockets = [];//fakeDB
wss.on("connection",(backSocket) => {// on: backend(server)의 eventListener임 -> 브라우저의 event에 귀 기울임
sockets.push(backSocket);//fakeDB에 연결된 socket(브라우저 혹은 유저) 넣어주기
backSocket["nickname"] = "Anonymous"; //아직 닉네임 정하지 않은 사람.
console.log("Connected to Browser ✅");
backSocket.on("close", () => console.log("Disconnected to the Brower ❌"));//Browser 연결이 끊기면 알려주는 콘솔창
backSocket.on("message",(msg) =>{
const message = JSON.parse(msg);
switch (message.type){
case "new_message":
sockets.forEach((aSocket) => {aSocket.send(`${backSocket.nickname}: ${(message.payload).toString()}`)});
case "nickname":
backSocket["nickname"] = message.payload;// socket에 닉네임 넣어주기
};
});
});
server.listen(3000,handleListen);
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")
link(rel="stylesheet", href="https://unpkg.com/mvp.css")
title Noom
body
header
h1 Noom
main
form#nick
input(type="text", placeholder="Choose a nickname", required)
button Save
ul
form#message
input(type="text", placeholder="Write a message", required)
button Send Message
script(src="/public/js/app.js")
우리는 현재 우리가 보내는 것이 아닌, 우리가 받는 메시지를 화면에 그리고 있음. -> 우리가 보내는 메 시지를 화면에 그리도록 코드 수정 ㄱ ㄱ
하지만 이렇게 되면 받는 메시지도 화면에 그리고, 보내는 메시지도 화면에 그리게 됨. 따라서 나는 메시 지를 나를 제외한 모든 사람들에게 보내도록 수정할 것임.
backend에서 message를 JSON.string형태로 보내고, frontend에서 JSON.parse해주기
이 외에도 여러 부수기능을 하나하나 새로 만들어야 돼서 다음 섹터에서는 framework를 이용해서 만들것임. wss는 기본적인 protocol이라, 아무 기능도 없었음 ㅆㅃ!