~1.9까지의 강의
home.pug
ul
form
input(type="text", placeholder="write a msg", required)
button Send
form을 만들어 우리가 보게될 메시지 리스트를 만들 것이다.
그리고 추가한 것을 찾게 하기 위해서 app.js에서 편집을 해준다.
app.js
const messageList = document.querySelector("ul");
const messageForm = document.querySelector("form");
home.pug와 연결시키는 부분들이다.
그리고, 메시지를 send하는 부분을 지우고 아래와 같이 변경한다.
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(input.value);
input.value = "";
}
messageForm.addEventListener("submit", handleSubmit);
이렇게 되면 socket은 input의 값을 보내주는 것이고, 다시 초기화 하는 것이다.
초기화
input.value="";
여기까지 하면 다른 브라우저에서 메세지를 쓰면 받지 못한다.
각자 다른 브라우저에서 메세지를 주고 받게 하려면 어떻게 해야할까?
sever.js
const sockets = [];
wss.on("connection", (socket) => {
sockets.push(socket);
console.log("Connected to Browser ✅");
socket.on("close", onSocketClose);
socket.on("message", (message) => {
sockets.forEach((aSocket) => aSocket.send(message.toString()));
});
});
누군가 서버에 연결하면, connection을 넣는다.
이렇게 하면 받은 메시지를 모든 socket에 전달해줄 수 있다.
즉, 메시지를 받으면 받은 메시지를 sockets에 있는 모든 곳에 전달해줄 수 있다.
그 후에 메시지를 socket에 다시 메시지를 보낸다.
socket.forEach((aSocket => aSocket.send(message.toString()))
각 브라우저를 aSocket으로 표시하는 것이다.
이렇게 하면 chat을 해줄 수 있다.
이제 메시지를 스크린에 보여주는 function을 만들어 보자 !
app.js
socket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
새로운 메시지를 받으면, 새로운 li를 만든 후에 message.data를 li안에 넣어준다.
우선 단순하게 메시지를 확인할 수 있다.
닉네임도 주고 받아보자.
home.pug
main
form#nick
input(type="text", placeholder="choose a nickname", required)
button Save
ul
form#message
input(type="text", placeholder="write a msg", required)
button Send
id를 만들어 주었다.
app.js
const nickForm = document.querySelector("#nick");
const messageForm = document.querySelector("#message");
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit)
home과 연동을 해주기 위해서 메세지폼도 변경한 것이다.
그리고 밑에 eventLister로 추가해준다.
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message",input.value));
input.value = "";
}
function handleNickSubmit(event) {
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send(makeMessage("nickname", input.value));
}
type을 지정해주어야 한다.
1가지는 메세지이다. 여기는 payload가 있다.
다른 타입은 닉네임이다. 사용하고 싶은 닉네임이 들어가는 것이다.
그러면 2가지 타입을 구별해줄 수 있다.
makeMessage
function makeMessage(type, payload) {
const msg = { type, payload };
return JSON.stringify(msg);
}
이 함수를 통해 type, payload를 정할 수 있다.
오브젝트를 string으로 만든 후, 다시 오브젝트로 만드는 방법은 무엇일까?
그것은 json.stringify를 하면 볼 수 있다.
메시지를 전송할 때 마다 string을 전송해줄 것이다.
string을 보내기전에 오브젝트를 string으로 만들어준다.
여기까지면 성공 !
우리는 지금까지 백엔드로 string을 보내주었다.
그런데 string의 모양은 계속해서 변화하고 있다.
즉, 다른 form에서 전송하고 있다.
server.js
wss.on("connection", (socket) => {
sockets.push(socket);
socket["nickname"] = "Anon";
console.log("Connected to Browser ✅");
socket.on("close", onSocketClose);
socket.on("message", (msg) => {
const message = JSON.parse(msg);
switch (message.type) {
case "new_message":
sockets.forEach((aSocket) =>
aSocket.send(`${socket.nickname}: ${message.payload}`)
);
case "nickname":
socket["nickname"] = message.payload;
}
});
});
우리는 string을 보내주고 있다.({type:~~})
string을 js로 변환하기 위해서 JSON.parse를 사용한다.
parse는 string을 js로 바꿔준다.
그후 닉네임을 하려면 save를 저장해주어야 한다.
switch를 사용해서 닉네임 타입을 받은 후에 payload, 즉 닉네임을 socket안에 넣어주어야 한다.
익명 socket에 대해서도 생각해야 하는데, 그래서 socket에 연결될 때 기본 값을 정해주는 것이다.
메시지가 socket에 전송되고, type이 new_message이면, 메시지를 보내는 것이다.
즉, 닉네임 property를 socket오브젝트에 저장하고 있는 것이다.
전체코드
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
form#nick
input(type="text", placeholder="choose a nickname", required)
button Save
ul
form#message
input(type="text", placeholder="write a msg", required)
button Send
script(src="/public/js/app.js")
app.js
const messageList = document.querySelector("ul");
const nickForm = document.querySelector("#nick");
const messageForm = document.querySelector("#message");
const socket = new WebSocket(`ws://${window.location.host}`);
function makeMessage(type, payload) {
const msg = { type, payload };
return JSON.stringify(msg);
}
function handleOpen() {
console.log("Connected to Server ✅");
}
socket.addEventListener("open", handleOpen);
socket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
socket.addEventListener("close", () => {
console.log("Disconnected from Server ❌");
});
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message",input.value));
input.value = "";
}
function handleNickSubmit(event) {
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send(makeMessage("nickname", input.value));
input.value = "";
}
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);
server.js
import http from "http";
import WebSocket from "ws";
import express from "express";
const app = express();
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on http://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
function onSocketClose() {
console.log("Disconnected from the Browser ❌");
}
const sockets = [];
wss.on("connection", (socket) => {
sockets.push(socket);
socket["nickname"] = "Anon";
console.log("Connected to Browser ✅");
socket.on("close", onSocketClose);
socket.on("message", (msg) => {
const message = JSON.parse(msg);
switch (message.type) {
case "new_message":
sockets.forEach((aSocket) =>
aSocket.send(`${socket.nickname}: ${message.payload}`)
);
case "nickname":
socket["nickname"] = message.payload;
}
});
});
server.listen(3000, handleListen);
'Web Service > NodeJS' 카테고리의 다른 글
[ZOOM 클론 코딩] #4. SocketIO (1) | 2022.08.31 |
---|---|
[ZOOM 클론 코딩] #2. WebSockets (0) | 2022.08.04 |
[ZOOM 클론 코딩] #1. Set up (0) | 2022.07.30 |
댓글