์ค์๊ฐ ์ฑํ ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํฉ๋๋ค.
์ฑํ ํ๋ก๊ทธ๋จ์ ๊ตฌํํ์ฌ ๋ณด๋ด๊ธฐ & ๋ฐ๊ธฐ ๊ธฐ๋ฅ์ ์์ฑํฉ๋๋ค.
๋๋ค์ ์ถ๊ฐํ๊ธฐ -> ์ฑํ ์ ์ฐธ๊ฐํ ๋, ์ฌ์ฉ์๊ฐ ๋๋ค์์ ์ด์ฉํ ์ ์์ต๋๋ค.
์ฑํ ๋ฐฉ์ ๋ง๋ญ๋๋ค.
์ฑํ ๊ฒฝํ์ ๋ ์ข๊ฒ ํด์ฃผ๋ eventํ์ฉ์ ํฉ๋๋ค.
"OO๋์ด ์ ์ฅ/ํด์ฅ ํ์ต๋๋ค." / ์ค์๊ฐ ์ฑํ ๋ฐฉ ์ธ์์
์ต๋ช > ๋๋ค์ ์ถ๊ฐ > ์ฑํ ๋ฐฉ ์ปจ์ ์ ํ๊ธฐ
์๋ฒ์ ๋ฐฉ์ด ๋ช๊ฐ ์กด์ฌํ๋์ง ํ์ธ
- http์ websockets๋ ๋๋ค protocol์
๋๋ค.
- ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ http๊ฐ stateless๋ผ๋ ์ ์
๋๋ค.
- ์น์์ผ์ ํ๋ฒ ์ฐ๊ฒฐ์ด ์ฑ๋ฆฝ๋๋ฉด, ์๋ฐฉํฅ ์ฐ๊ฒฐ์ด ์๊น๋๋ค.
- ์น์์ผ์ request-reponse๊ฐ์๊ฒ ํ์์์ต๋๋ค.
- ๋ชจ๋ ์๋ฒ๋ค์ด ์๋ํ๋ ๋ฐฉ์์
๋๋ค.
- ์ ์ ๊ฐ request๋ฅผ ๋ณด๋ด๋ฉด ์๋ฒ๊ฐ response๋ก ๋ฐ์ํฉ๋๋ค.
- ์ ์ ๊ฐ ํ์ผ๋ก GET request๋ฅผ ๋ณด๋ด๋ฉด template์ผ๋ก ๋ฐ์ํฉ๋๋ค.
- ์ ์ ๊ฐ ์ด๋ค ํ์ด์ง๋ก GET request๋ฅผ ๋ณด๋ด๋ redirect๋ก ๋ฐ์ํฉ๋๋ค.
- ์ธํฐ๋ท ์ ์ฒด๊ฐ http๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ ธ์์ต๋๋ค.
- ํน์ง์ stateless์
๋๋ค, backend๊ฐ ์ ์ ๋ฅผ ๊ธฐ์ตํ์ง ๋ชปํฉ๋๋ค.
- ์ ์ ์ backend ์ฌ์ด์ ์๋ฌด๋ฐ ์ฐ๊ฒฐ์ด ์์ต๋๋ค.
- request์ response ๊ณผ์ ๋ค์, backend๋ ์ ์ ๋ฅผ ์์ด๋ฒ๋ฆฝ๋๋ค.
- ์๋ฒ๋ response๋ฅผ ์ฃผ๋ฉด ๋๋๊ณ , ๋ค์ request๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
- ์๋ฒ๋ ์ค์ง request๋ฅผ ๋ฐ์๋๋ง response๋ฅผ ์ค๋๋ค.
- GET request, POST request..๋ฑ๋ฑ requset, response์ ๊ณผ์ ์
๋๋ค.
- http๋ real-time์ผ๋ก ์ผ์ด๋์ง ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ๋ฐฑ์๋ ์ฌ์ด๋ฟ๋ง์๋๋ผ, ๋ฐฑ์๋์ ๋ฐฑ์๋ ์ฌ์ด์์๋ ์ผ์ด๋ฉ๋๋ค.
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));
- ์น์์ผ์ผ๋ก ์ค์๊ฐ ์ฑํ
, Notification๊ณผ ๊ฐ์ real-time์ ๋ง๋ค ์ ์์ต๋๋ค.
- webSocket์ ์ฌ์ฉํด์ ์ฐ๊ฒฐํ๊ณ ์ถ๊ณ , ์๋ฒ๊ฐ ์ง์ํ๋ค๋ฉด wss๋ฅผ ํ๋ฉด ๋ฉ๋๋ค.
- Secure Web Socket(WSS)
- http์๋ ์ ํ ๋ค๋ฅธ protocol์
๋๋ค.
- ์น์์ผ ์ฐ๊ฒฐ(connection)์ด ์ผ์ด๋ ๋ ๋ง์น ์
์์ฒ๋ผ ์๋ํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ๋ก websocket request๋ฅผ ๋ณด๋ด๋ฉด, ์๋ฒ๊ฐ ๋ฐ๊ฑฐ๋ ๊ฑฐ์ ํฉ๋๋ค.
- ์ด๋ฐ ์
์(connection)์ด ํ๋ฒ ์ฑ๋ฆฝ๋๋ฉด, ์ฐ๊ฒฐ์ ์ฑ๋ฆฝ(establish)๋ฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ์๋ฒ๋ ์์ ๋ง์ก๊ณ ์๋ ๊ฒ์ฒ๋ผ ์ฐ๊ฒฐ๋ฉ๋๋ค.
- ํฐ๋๊ณผ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ์ ์๋ฒ๊ฐ ์๋ก ์ปค๋ฎค๋์ผ์ด์
ํฉ๋๋ค.
- ์ฐ๊ฒฐ๋์ด์๊ธฐ์, ์๋ฒ๋ ์ ์ ๊ฐ ๋๊ตฐ์ง ๊ธฐ์ตํฉ๋๋ค.
- ์ฐ๊ฒฐ๋์ด์๊ธฐ์, ์๋ฒ๋ ์ ์ ์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
- ์๋ฒ๋ ์ด์ํ์์ request๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์๋ ๋ฉ๋๋ค, ์๋ฒ๊ฐ ๋ต์ฅํ ์ ์์ต๋๋ค.
- request, response ๊ณผ์ ์ด ํ์ํ์ง์๊ณ , ๊ทธ๋ฅ ๋ฐ์ํฉ๋๋ค.
- ์ ๋ฑกํฅ์ ์ฐ๊ฒฐ(bi-directional)์ด๋ผ๊ณ ํฉ๋๋ค.
- ์๋ฒ๋ ์ ์ ์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์๊ณ ์ ์ ๋ ์๋ฒ์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
- ์ด ๋ชจ๋ ๊ฒ์ connection(์ฐ๊ฒฐ) ์ค์ผ๋๋ง ๋ฐ์ํฉ๋๋ค.
- ์๋ก ์ ๊ทผํ ์ ์๊ธฐ์ ์๋ฒ์ ์ ์ ๋ ์ด๋๋๋ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ์๋ฒ ์ฌ์ด์ bi-directionalํ ์ฐ๊ฒฐ์ด ์์ด์
์๋ก์๊ฒ ๋ฐ๋ก ๊ฐ ์ ์๋ ๊ธธ์ด ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ์๋ฒ ๊ฐ์ ์ค์๊ฐ์ผ๋ก ๊ณ์ ์๋ก ์ฐ๊ฒฐ๋์ด์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ์๋ ๋ด์ฅ๋ webSocket API๊ฐ ์์ต๋๋ค.
- ์๋ฒ์ ์ฐ๊ฒฐํ๊ธฐ์ํด ๋ธ๋ผ์ฐ์ ์์ webSocket์ ์ฌ์ฉํฉ๋๋ค.
- ์น์์ผ์ ํ๋กํ ์ฝ์ผ๋ฟ, ์ด๋ค ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๊ตญํ๋์ด์์ง ์์ต๋๋ค.
- ์น์์ผ์ ๋ธ๋ผ์ฐ์ ์ ๋ฐฑ์๋ ์ฌ์ด์์๋ง ๋ฐ์ํ์ง ์๊ณ ,
2๊ฐ์ ๋ฐฑ์๋ ์ฌ์ด์์๋ ์๋ํฉ๋๋ค.
- real-time์ผ๋ก ์ํตํ๋ 2๊ฐ์ ์๋ฒ ์ฌ์ด์์๋ ์๋ํฉ๋๋ค.
- ws๋ผ๋ package์ ๋์์ ๋ฐ์ต๋๋ค.
- implementation(์คํ)
- ํ๋กํ ์ฝ์ด๋, ์ด๋ค ์ฌ๋๋ค์ด ์ด๋๊ฐ์ ์๋ ๋ฐฉ์์ ๋ง๋๊ณ ,
์ด๋ ํ ์ผ์ด ์งํ๋ ์ง ๊ฒฐ์ ํฉ๋๋ค.
- ์ด๋ป๊ฒ ๋ชจ๋ ๊ฒ์ด ๋์๊ฐ์ผ ํ ์ง์ ๋ํ ๊ท์น์ ๋ง๋ญ๋๋ค.
- ํ๋ก๊ทธ๋๋จธ๋ ์ด ๊ท์น์ ๊ฐ์ง๊ณ ์ด ๊ท์น์ ๋ฐ๋ฅด๋ ์ฝ๋๋ฅผ ๋ง๋ค์ด์ ์คํํฉ๋๋ค.
- ์ฌ๋๋ค์ด ๋ฐฉ์ ๋ชจ์ฌ ํ์ค์ด ๋๋ ๊ท์น, ํ๋กํ ์ฝ์ ๋ง๋ญ๋๋ค.
- ๊ทธ ํ์ ๊ฐ๋ฐ์๋ค์ด ์ด ๊ท์น์ ์ฝ๋์ ๋
น์ฌ๋
๋๋ค.
- ๊ทธ๋์ NodeJS๋ฅผ ์ํ webSocket implementation์ด๋ผ๊ณ ํ๋ ๊ฒ ์
๋๋ค.
- GO,JAVA,NodeJS์์๋ webSocket implementation์ ์ฐพ์ ์ ์์ต๋๋ค.
- ws๋ webSocket ํ๋กํ ์ฝ์ ์คํํ๋ package๋ฅผ ๋งํฉ๋๋ค.
- ws ์ฌ์ฉ์ ๋์ผ๋ก ๋ง๋ฌด๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ ํ์ ๋ณ๊ฒฝํ ๊ฒ์
๋๋ค.
- ws๋ nodeJS์์๋ webSocket์ ํต์ฌ์ธ ํจํค์ง
- ws์ implementation์ผ๋ฟ์ด๋ฉฐ, webSocket์ ํต์ฌ์
๋๋ค.
- ์ฑํ
๋ฐฉ์ webSocket ํ๋กํ ์ฝ์ ์ผ๋ถ๋ถ์ด ์๋๋๋ค.
- ์ฑํ
๋ฐฉ์ feature, ๊ธฐ๋ฅ์ผ๋ฟ์
๋๋ค.
- ws๋ง์ ๊ฐ์ง๊ณ ์ฑํ
๋ฐฉ์ ๋ง๋ค๋ ค๋ฉด, ํน์ ์ logic์ ๊ฐ๋ฐ์๊ฐ ๊ตฌํํด์ผ ํฉ๋๋ค.
- ๋๋ฌธ์ ws๋ฅผ ์ด์ฉํ framework๊ฐ ๋ง๋ค์ด์ ธ ์์ต๋๋ค.
- ํ๋ก์ ํธ์ ๋ถ์ผ framework์๋ ์ฑํ
๋ฐฉ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
- ๋๋ฌธ์ ์๋ฌด๊ฒ๋ ๋ง๋ค ํ์๊ฐ ์์ผ๋ฉฐ, ws๋ webSocket์ core์
๋๋ค.
- ws๋ ์์ฃผ ๊ธฐ์ด์ ์ธ ๊ธฐ๋ฅ์ด๋ฉฐ, ๋ถ๊ฐ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
๐ ws๋ฅผ ์ฌ์ฉํ๋ framework๋ฅผ ๊ฐ๋ฐ์๊ฐ ์์ ํฉ๋๋ค.ws package๋ฅผ ์ด์ฉํ ๊ธฐ๋ณธ์ ์ธ webSocket ์ฌ์ฉ > ws๋ฅผ ์ด์ฉํ๋ framework ์ฌ์ฉํ๊ธฐ
npm i ws
- express๋ ws๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.
- createServer๋ฅผ ํ๋ ค๋ฉด requestListener๊ฒฝ๋ก๊ฐ ์์ด์ผํฉ๋๋ค.
- express application์ผ๋ก๋ถํฐ ์๋ฒ๋ฅผ ๋ง๋ญ๋๋ค.
- ์๋ฒ์์ http, webSocket ๋ ๋ค ์๋ ์ํต๋๋ค.
- ์ค์ง webSocket๋ง์ ์๋ํ๊ฒ ํ ์๋ ์์ต๋๋ค.
- 2๊ฐ์ง๊ฐ ๊ฐ์ ํฌํธ์ ์๊ฒํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด ์์
ํฉ๋๋ค.
- http์๋ฒ๋ฅผ express.js๋ฅผ ์ด์ฉํด์ ๋ง๋ค์์ต๋๋ค.
- http์๋ฒ ์์ webSocket์๋ฒ๋ฅผ ๋ง๋ค์์ต๋๋ค.
- ์๋ฒ๋ฅผ ๋ง๋ค๊ณ , http์๋ฒ ์์ ws์๋ฒ๋ฅผ ๋ง๋ญ๋๋ค.
- ๊ทธ๋ฌ๋ฏ๋ก localhost๋ ๋์ํ ํฌํธ์์ http,
ws request ๋ ๊ฐ์ง๋ฅผ ๋ค ์ฒ๋ฆฌํฉ๋๋ค.
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("/", (req, res) => res.render("home"));
app.get("/*", (req, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on ws://localhost:3000`);
//http์ webSocket ๋๋ค ์ฌ์ฉํ ์ ์์ต๋๋ค.
const server = http.createServer(app);
const wss = new WebSocket.Server({server});
//server๋ฅผ listen
//๋ด http์๋ฒ์ ์ ๊ทผํ๋ ค๊ณ ํฉ๋๋ค.
server.listen(3000, handleListen);
๐ ... ์๋ฒ๋ http, ws 2๊ฐ์ protocol์ ์ดํดํ ์ ์๊ฒ๋ฉ๋๋ค.
http์๋ฒ๊ฐ ์์ผ๋ฉด, ๊ทธ ์์์ ws์๋ฒ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
2๊ฐ์ ํ๋กํ ์ฝ์ด ๋ค ๊ฐ์ port๋ฅผ ๊ณต์ ํฉ๋๋ค.
ํ์ฌ ์๋ฒ๋ http protocol
ws connection(์ฐ๊ฒฐ)
์ ์ง์ํฉ๋๋ค.
http ์๋ฒ๊ฐ ํ์ฌ ํ์ํ ์ด์ ๋, views, static files, home, redirection์ ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
๐ ws์๋ฒ๊ฐ ์์ฑ๋์์ต๋๋ค.
- WebSocket Event
- ws๋ฅผ ์ฌ์ฉํ์ฌ backend์ frontend ์ฌ์ด์์ ์ฐ๊ฒฐ์ ๋ง๋ญ๋๋ค.
- FE์์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฏธ webSocket ํด๋ผ์ด์ธํธ์
๋ํimplementation์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- webSocket์ ์ด์ฉํด BE์ JS๋ก ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
- ์๋ฌด๊ฒ๋ ์ค๋นํ ํ์ ์์ด ๋ธ๋ผ์ฐ์ ์์ ์ง์๋ฉ๋๋ค.
- url์ ์ ์ธํ๊ณ , ์ ์ ๊ฐ url๋ก ๊ฐ๋ฉด, req๊ณผ res๋ฅผ ๋ฐ๊ณ response๋ฅผ ๋ณด๋
๋๋ค.
- app.js(FE)์ ๋ฒํผ์ ๋ง๋ญ๋๋ค.
- webSocket๋ event๊ฐ ์๊ณ , event๊ฐ ๋ฐ๋๋ ๋,
์ฌ์ฉํ function์ ๋ง๋ญ๋๋ค.
- webSocket์ listenํ ํน์ ํ event๋ช
์ด ์์ต๋๋ค.
- ws์์๋ ์ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ๋ฐ์ function์ด ์กด์ฌํฉ๋๋ค.
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
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 ws://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
- click, submit, Wi-Fi on/off
- webSocket์๋ event๊ฐ ์์ต๋๋ค.
- socket์ด๋ ์ฐ๊ฒฐ๋ ์ด๋ค ์ฌ๋์
๋๋ค.
- ์ฐ๊ฒฐ๋ ๋ธ๋ผ์ฐ์ ์์ contact(์ฐ๋ฝ)๋ผ์ธ์
๋๋ค.
- socket์ ์ด์ฉํ๋ฉด ๋ฉ์์ง ์ฃผ๊ณ /๋ฐ๊ธฐ๋ฅผ ํ ์ ์์ต๋๋ค.
- ์ด ์ฐ๊ฒฐ์ ์ด๋๊ฐ์ ์ ์ฅ(save)ํด์ผ ํฉ๋๋ค.
- on๋ฉ์๋์์๋ event๊ฐ ๋ฐ๋ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฝ๋๋ค.
- connection์ด ์ด๋ฃจ์ด์ง๋ฉด function์ด ๋ฐ๋ํฉ๋๋ค.
- on ๋ฉ์๋๋ BE์ ์ฐ๊ฒฐ๋ ์ฌ๋์ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๊ทธ๊ฒ์ด ์ฌ๊ธฐ socket์์ ์ต๋๋ค.
- socket์ด๋ ์๋ฒ์ ๋ธ๋ผ์ฐ์ ์ฌ์ด์ ์ฐ๊ฒฐ์
๋๋ค.
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("/", (req, res) => res.render("home"));
app.get("/*", (req, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on ws://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
function handleConnection(socket) {
console.log(socket);
}
wss.on("connection", handleConnection);
server.listen(3000, handleListen);
๐... ์ด๋ ๊ฒ ์์ฑํ๋ ๊ฒ์ vanillaJS๋ฅผ ํ ๋๋ง ์
๋๋ค.
event๋ฅผ listenํ๊ณ , ์ด๋๊ฐ์ handler๋ฅผ ๋ง๋ค์์ ๋๋ง ์ด๋ ๊ฒ ํฉ๋๋ค.
์ง๊ธ์ ์ด๋๋ก๊ณ , webSocket์ ์ด์ฉํด์ ์๋ก์ด connection์ ๊ธฐ๋ค๋ฆฝ๋๋ค.
- FE์ BE๋ ์ฐ๊ฒฐํด๋ฌ๋ผ๊ณ ์์ฑํด์ผํฉ๋๋ค.
- ์ด๊ฒ์ด ์ด๋ฃจ์ด์ง๋ฉด, handleConnectionํจ์์ console.log๊ฐ ์คํ๋ฉ๋๋ค.
- webSocket ์ฐ๊ฒฐ์ด ๋ฐ์ํ๋๋ก ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
- FE์์ BE๋ก ์ฐ๊ฒฐํ๋ ์ฝ๋ :
const socket = new WebSocket("ws://localhost:3000");
- ws(WebSocket) ์ด๊ฑฐ๋ wss(WebSocket Secure)์ฌ์ผํฉ๋๋ค.
- new WebSocket ๋ด๋ถ URL๋ด๋ถ์ http๋ฅผ ws๋ก ๋ณ๊ฒฝํ๊ณ
- localhost:3000๊ฐ์ ํฌํธ๋ฒํธ๋ฅผ ์ง์ ์ ์ผ๋ก ์์ฑํ์ง ์์ต๋๋ค.
ex) ํด๋ํฐ์ผ๋ก ํด๋ณด๋ฉด ๋น์ฐํ ํด๋ํฐ์ ๋ก์ปฌํธ์คํธ ํฌํธ๋ฒํธ 3000๋ฒ์ ์กด์ฌํ์ง ์๊ธฐ๋๋ฌธ์ ๋๋ค.
- ํฌํธ๋ฒํธ ๋์ , ํ์ฌ ์ ์ ๊ฐ ์ด๋์๋์ง์ ๋ํ ์ ๋ณด๋ฅผ ์ค๋๋ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ ์ค์ค๋ก ์ด ํฌํธ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ค๊ฒ ํฉ๋๋ค.
- window.location.host (localhost:3000) ์ ๋ณด๊ฐ ์์ต๋๋ค.
const socket = new WebSocket(`ws://${window.location.host}`);
...๋ค์ ์ฐ๊ฒฐํด์ ์ฝ์์ฐฝ์ ๋ณด๋ฉด, ์ฐ๋ฆฌ๊ฐ ํ์ํ socket์ ์ฝ์์ ์ฐ์ด์ค๋๋ค. webSocket์ ๋ธ๋ผ์ฐ์ ์ ์๋ฒ ์ฌ์ด์ ์ฐ๊ฒฐ์ ๋๋ค.
๐ socket์ด FE์ real-time์ผ๋ก ์ํตํ ์ ์์ต๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก, FE์๋ socket์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
FE์์ BE๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
- server.js์ socket์ ์ฐ๊ฒฐ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ฏธํฉ๋๋ค.
- app.js์ socket์ ์๋ฒ๋ก์ ์ฐ๊ฒฐ์ ์๋ฏธํฉ๋๋ค.
- connection์์ ๊ฐ์ ์ญํ ์ ํ๋ ์ต๋ช
ํจ์๋ฅผ ๋ง๋ญ๋๋ค.
- socket์ ์๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ด
๋๋ค.
- ์๋ฒ์ ์๋ ๊ฒ์ด ์๋๋ผ, socket์ ์๋ ๋ฉ์๋์
๋๋ค.
- ์ด ๋ฉ์๋๋ socket์ผ๋ก ์ง์ ์ ์ธ ์ฐ๊ฒฐ์ ์ ๊ณตํฉ๋๋ค.
- ๋ฐฑ์๋์์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด (server.js)
- ํ๋ก ํธ์์ ๋ฐ๋ ์ฒ๋ฆฌ๋ ํด์ค์ผํฉ๋๋ค. (app.js)
- message๋ ์ด๋ฒคํธ์
๋๋ค. ์ด๋ฒคํธ๋ฅผ FE์์ ๋ฐ์ต๋๋ค.
- "connection" ์ด๋ฒคํธ, ์ปค๋ฅ์
์ด ์๊ธฐ๋ฉด, socket์ผ๋ก ์ฆ์ ๋ฉ์์ง๋ฅผ ๋ณด๋
๋๋ค.
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("/", (req, res) => res.render("home"));
app.get("/*", (req, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on ws://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on("connection", (socket) => {
console.log("Connected to Browser โ
");
socket.send("helllo");
});
server.listen(3000, handleListen);
wss.on("connection", (socket) => {
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.send("helllo");
});
server.listen(3000, handleListen);
FE์์ ๋ณด๋ธ ๋ฉ์์ง๋ฅผ BE์์ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ
๋๋ค.
๊ทธ๋ฌ๋, BE์์ FE๋ก ๋ณด๋ธ ๋ฉ์ธ์ง๋ฅผ ๋ฐ๋ ๋ฐฉ๋ฒ์ ์๋๋ค.
FE์์ BE๋ก ์ฐ๊ฒฐ์ ๋ง๋ค์ด์ฃผ๊ณ , BE๋ connection์ ๊ธฐ๋ค๋ฆฌ๋ฉด,
eventlistener๋ฅผ ๋ฑ๋กํ๊ณ ๋ค์์ผ๋ก ๋์ด๊ฐ๋ฉด ๋ฉ๋๋ค.
๋งค๋ฒ ์๋ก์ด ๋ธ๋ผ์ฐ์ ๊ฐ BE๋ก ์ฐ๊ฒฐํ ๋, ํ์ ๊ตฌํ ์ฝ๋๋ค์ด BE์ ์ฐ๊ฒฐ๋
๊ฐ ๋ธ๋ผ์ฐ์ ์ ๋ํด ์๋ํฉ๋๋ค.
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("/", (req, res) => res.render("home"));
app.get("/*", (req, res) => res.redirect("/"));
const handleListen = () => console.log(`Listening on ws://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on("connection", (socket) => {
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
console.log(translatedMessageData);
});
socket.send("helllo");
});
server.listen(3000, handleListen);
const socket = new WebSocket(`ws://${window.location.host}`);
//socket์ด open๋์๋ค๋ฉด, ๋ธ๋ผ์ฐ์ ์ ์ฐ๊ฒฐ๋์๋ค๊ณ ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
//socket์ด connection์ openํ์๋ ๋ฐ์ํฉ๋๋ค.
socket.addEventListener("open", () => {
console.log("Connected to SERVER โ
");
});
socket.addEventListener("message", (message) => {
console.log("New message: ", message.data, " from the SERVER.");
});
socket.addEventListener("close", () => {
console.log("Close SERVER โ");
});
setTimeout(() => {
socket.send("hello from the browser");
}, 1000);
- html ํผ ๊ตฌ์กฐ๋ฅผ ์์ฑํฉ๋๋ค. (form, input, button)
main
ul
form
input(type="text", placeholder="write a message", required)
button Send
-FE์ form์์ BE๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ณ ์์ต๋๋ค.
const messageList = document.querySelector("ul");
const messageForm = document.querySelector("form");
const socket = new WebSocket(`ws://${window.location.host}`);
//socket์ด open๋์๋ค๋ฉด, ๋ธ๋ผ์ฐ์ ์ ์ฐ๊ฒฐ๋์๋ค๊ณ ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
//socket์ด connection์ openํ์๋ ๋ฐ์ํฉ๋๋ค.
socket.addEventListener("open", () => {
console.log("Connected to SERVER โ
");
});
socket.addEventListener("message", (message) => {
console.log("New message: ", message.data, " from the SERVER.");
});
socket.addEventListener("close", () => {
console.log("Close SERVER โ");
});
// setTimeout(() => {
// socket.send("hello from the browser");
// }, 1000);
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(input.value);
console.log(input.value);
}
messageForm.addEventListener("submit", handleSubmit);
- BE์์ ๋ฉ์์ง๋ฅผ ๋ฐ์ผ๋ฉด ๊ฐ์ ๋ฉ์์ง๋ฅผ ๋ค์ FE๋ก ์ ๋ฌํฉ๋๋ค.
- BE์์ FE๋ก ๋ฐ์ ๋ฉ์์ง๋ฅผ ๋์ผํ๊ฒ ๋ค์ ๋๋ ค๋ณด๋
๋๋ค.
- ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด์ด์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด,
ํ๊ฐ์ ์๋ฒ๊ฐ ์๋ก ๋ค๋ฅธ 2๊ฐ์ ๋ธ๋ผ์ฐ์ ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๋ฐ์ต๋๋ค.
- ๊ทธ ๋ฉ์์ง์ ์๋ฒ๊ฐ ๊ฐ๊ฐ ๋ต์ฅ์ FE์ฝ์๋ก ์ฐ์ด์ค๋๋ค.
- ์๋ก ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ๋ ์๋ก ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค.
ex) [firefox] -> ws <- [์๋ฒ] -> ws <- [chrome]
- ์ด์ firefox์์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด ์๋ฒ๋ก ๊ฐ๋ค๊ฐ
๊ทธ๊ฒ chrome์ผ๋ก ์ ๋ฌ๋๋๋ก ๊ตฌํํฉ๋๋ค.
wss.on("connection", (socket) => {
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
socket.send(translatedMessageData);
});
});
- ์๋ฒ๊ฐ firefox๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๋ฐ์์ safari์ ์ ๋ฌํฉ๋๋ค.
- ๋๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ๋์ด์๋์ง ์์์ผํฉ๋๋ค.
- ํ์ฌ๋ ๋๊ฐ ์ฐ๊ฒฐ๋์ด์๋์ง ์ ์ ์์ต๋๋ค.
- wss.on๋ฉ์๋๋ 2๋ฒ ์๋ํฉ๋๋ค.
- ๊ฐ์ ์ฝ๋๊ฐ 2๊ฐ์ ๋ธ๋ผ์ฐ์ ์ ์ฐ๊ฒฐ๋ ๊ฒ์
๋๋ค.
- fake database๋ฅผ ๋ง๋ญ๋๋ค.
- ๋๊ตฐ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐํ๋ฉด ๊ทธ connection์ sockets ๋ฐฐ์ด์ ๋ฃ์ต๋๋ค.
- ์ฐ๊ฒฐ๋ sockets๋ฅผ ๋ฐฐ์ด๋ก ๋ณด๊ดํ๋ฉด ๋ฐ์ ๋ฉ์์ง๋ฅผ
๋ชจ๋ socket์๊ฒ ๋ณด๋ผ ์ ์์ต๋๋ค.
-
const sockets = [];
wss.on("connection", (socket) => {
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
socket.send(translatedMessageData);
});
});
- ์ฐ๊ฒฐ๋ ๋ชจ๋ socket๋ค์ ์ ๊ทผํ ์ ์์ต๋๋ค.
- ๋ค๋ฅธ socket์๊ฒ๋ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ์ง๋ง ์๊ธฐ ์์ ์๊ฒ๋ ์ ๋ฌํ๊ณ ์์ต๋๋ค.
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
const sockets = [];
wss.on("connection", (socket) => {
sockets.push(socket);
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
sockets.forEach(aSocket => aSocket.send(translatedMessageData));
});
});
- JS๋ก li๋ง๋ค๊ณ list์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ์์๋ฅผ ๋ถ์
๋๋ค.
socket.addEventListener("message", (message) => {
//console.log("New message: ", message.data, " from the SERVER.");
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
- ๋ํ๋ ์ต๋ช
์ผ๋ก ์งํ๋๋ฉฐ ์๋ก์ ์์ผ์ ๊ตฌ๋ณํ ์ ์๋ nickName์ด ์์ต๋๋ค.
- ์๋ก์ด form์ ๋ง๋ค์ด์ nickname์ ์ ํ ์ ์๋๋ก ํฉ๋๋ค.
- ๋ฌธ์ ๋ BE๋ก nickname์ ๋ณด๋ด์ผ ํ๋ค๋ ๊ฒ์
๋๋ค.
- ํ์ง๋ง BE๋ message๋ค์ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
- message๋ฅผ ๊ตฌ๋ถํ ์ ์๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค.
ex) 1. nickName์ ์ ์ฅํ๊ธฐ์ํ ๋ฉ์์ง,
2. ๋ค๋ฅธ ๋ฉ์์ง๋ chat์์ ๋ค๋ฅธ ์ฌ๋์๊ฒ ๋ณด๋ด์ง๋ ๋ฉ์์ง
- ํ์ฌ๋ ํด๋น ์ฌํญ์ ๋ํ ๋ถ๊ธฐ์ฒ๋ฆฌ๊ฐ ๋์ด์์ง ์์ ์๋ฌด ๋ฉ์์ง๋ ํด๋น๋ฉ๋๋ค.
- ๋ฉ์์ง type์ ๋ง๋ญ๋๋ค.
- 1. message chat, 2. nickname
- ๋๋ฌธ์ message๋ฅผ text๊ฐ ์๋ json์ผ๋ก ๋ณด๋ด์ ๊ตฌ๋ถํฉ๋๋ค.
{
type:"message",
payload:"hello everyone"
}
{
type:"nickName",
payload:"harry"
}
send ๋ฉ์๋๋ ๋ฐ์ดํฐ๋ฅผ stringํ์ ๋ง ๋ณด๋ผ ์ ์์ต๋๋ค.
const messageList = document.querySelector("ul");
const messageForm = document.querySelector("#message");
const nickForm = document.querySelector("#nick");
const socket = new WebSocket(`ws://${window.location.host}`);
socket.addEventListener("open", () => {
console.log("Connected to SERVER โ
");
});
socket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
socket.addEventListener("close", () => {
console.log("Close SERVER โ");
});
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(input.value);
input.value = "";
}
function handleNickSubmit(event) {
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send({
type: "nickname",
payload: input.value
});
}
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);
text๊ฐ ์๋ json๊ฐ์ฒด๋ฅผ ์ ์กํฉ๋๋ค. nicknameํผ์์ ๊ฐ์ฒด๊ฐ ์ ์ก๋๋ฉด ๋ฆฌ์คํธ์ ์ถ๋ ฅ๋ฉ๋๋ค.
์๋ฒ๋ ํ๋ฉด์ [object Object]
๋ผ๋ ํ
์คํธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
on๋ฉ์๋๋ก๋ string๋ง ์ ์ก๋๊ธฐ๋๋ฌธ์
๋๋ค.
string์ ์ ์กํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์? ๋จ, json์ผ๋ก ์ธ ์ ์์ด์ผํฉ๋๋ค. -> JSON.stringfy()
์
๋๋ค.
BE์์ string์ ๊ฐ์ ธ๋ค๊ฐ JSON.parseํ ์ ์์ต๋๋ค.
๐ object๋ฅผ ๊ฐ์ ธ์์ string์ผ๋ก ๋ฐ๊ฟ์ผํฉ๋๋ค. > string๋ง ์ ์ก๊ฐ๋ฅ
string์ผ๋ก ๋ฐ๋ object๋ BE์ผ๋ก ์ ์ก๋ฉ๋๋ค.
BE์์๋ ๊ทธ string์ ๋ค์ object๋ก ๋ฐ๊พธ์ด์ค๋๋ค.
BE์์ socket์ผ๋ก ๋ฉ์์ง๋ฅผ ์ ์กํ๊ธฐ ์ํด์๋ object๋ฅผ ๊ฐ์ ธ์์ string์ผ๋ก ๋ง๋ค์ด์ค์ผ ํฉ๋๋ค.
FE์์๋ ๋์ผํ๊ฒ ๊ทธ string์ ๊ฐ์ ธ์์
์๋ก์ด ๋ฉ์์ง๊ฐ ์์๋, ๊ทธ string์ object๋ก ๋ง๋ค์ด์ผํฉ๋๋ค.
const messageList = document.querySelector("ul");
const messageForm = document.querySelector("#message");
const nickForm = document.querySelector("#nick");
const socket = new WebSocket(`ws://${window.location.host}`);
function makeMessage(type, payload) {
const ms = { type, payload }
return JSON.stringify(msg);
}
socket.addEventListener("open", () => {
console.log("Connected to SERVER โ
");
});
socket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
socket.addEventListener("close", () => {
console.log("Close 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));
}
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);
BE๋ก ๋ฉ์์ง๋ฅผ ์ ์กํ ๋๋ง๋ค, string์ ์ ์กํด์ค๋๋ค.
string์ ๋ณด๋ด๊ธฐ์ ์ object๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ๊ฐ์ฒด๋ฅผ string์ผ๋ก ๋ง๋ญ๋๋ค.
BE๊ฐ ๋ฉ์์ง๋ฅผ ๋ค์ ์ ์กํด์ฃผ๊ณ ์์ต๋๋ค.
- 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- nickname type์ ๋ฉ์์ง๋ฅผ ๋ฐ๋๋ค๋ฉด,
์ด connection์์ nickname์ ์ค์ ํด์ค์ผํฉ๋๋ค.
- ๋ง์ฝ new_message type์ ๋ฉ์์ง๋ฅผ ๋ฐ๋๋ค๋ฉด, ํ๋ฉด์ ๋ณด์ฌ์ค๋๋ค.
- string์ ๋ชจ์์ ๋ชฉ์ ์ ๋ฐ๋ผ์ ๋ฌ๋ผ์ง๋๋ค.
- FE์์ ๋ณด๋ด๊ณ ์ถ์ ๋ฉ์์ง๊ฐ 2๊ฐ ์์ต๋๋ค.
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message", input.value));
input.value = "";
}
... ์ด๋ถ๋ถ์ ๋ฉ์์ง๋ chat์ผ๋ก ๋ณด๋ด๋ ๋ฉ์์ง์ ๋๋ค.
function handleNickSubmit(event) {
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send(makeMessage("nickname", input.value));
}
...์ด๋ถ๋ถ์ ๋ฉ์์ง๋ nickname์ ๋ณ๊ฒฝํ๊ณ ์ถ์ ๋, BE์ผ๋ก ๋ณด๋ด๊ณ ์์ต๋๋ค.
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);
form์ด 2๊ฐ์ด๊ธฐ๋๋ฌธ์, ์๋ก ๋ค๋ฅธ form์์ ์ ์ก๋๊ณ ์์ต๋๋ค.
๋ฌธ์ ๋ BE๊ฐ JS object๋ฅผ ์ ํ ์ดํดํ์ง ๋ชปํฉ๋๋ค. (string๋ง ๋ณด๋ผ ์ ์์ต๋๋ค.)
๐ ์ค๋ก์ง ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์๋ง ์์กดํ๋ฉด ์๋ฉ๋๋ค.
BE๋ก JS object๋ฅผ ๋ณด๋ด๋ฉด ์ข์ง ์์ต๋๋ค. ์๋ํ๋ฉด, ์ฐ๊ฒฐํ๊ณ ์ถ์ FE์ BE ์๋ฒ๊ฐ JS์๋ฒ๊ฐ ์๋ ์๋ ์๊ธฐ๋๋ฌธ์ ๋๋ค.
(Java ์๋ฒ์ผ์๋ ์์ผ๋ฉฐ, GO์๋ฒ ์ผ์๋ ์์ต๋๋ค.)
... ์ด๋ฌํ ์ด์ ๋ก JS object๋ฅผ BE๋ก ๋ณด๋ด๋ฉด ์๋ฉ๋๋ค.
ํ์ฌ ์ด ์๋ฒ๋ JS๋ก ๋ง๋ค์๋๋ฐ, ๋๊ตฐ๊ฐ๋ GO๋ฅผ ์ด์ฉํด ์๋ฒ์ ์ ๊ทผํ๋ ค๊ณ ํ ์๋ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด, JS์ object๋ฅผ GO๋ก ๋ณด๋ด๋ฉด ์๋ฉ๋๋ค.
์ด๋ฌํ ์ด์ ๋ก BE์๋ string์ ๋ณด๋ด์ผํฉ๋๋ค.
๐ BE์ ์๋ ๋ชจ๋ ์๋ฒ๋ ๊ทธ string์ ๊ฐ์ง๊ณ ๋ญ ํ ์ง ์ ํฉ๋๋ค.
object๋ฅผ string์ผ๋ก ๋ฐ๊ฟ์ BE์ ๋๊ฒจ์ผํ๋ ์ด์ ๋
webSocket์ด ๋ธ๋ผ์ฐ์ ์ ์๋ API์ด๊ธฐ๋๋ฌธ์
๋๋ค.
BE์์๋ ๋ค์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ๋๋ฌธ์, ์ด API๋ ์ด๋ ํ ํ๋จ๋ ํด์๋ ์๋ฉ๋๋ค.
API๊ฐ ์ด๋ ํ ๊ฒฐ์ ๋ ํด์๋ ์๋๊ธฐ๋๋ฌธ์, string๋ง ๋ณด๋
๋๋ค.
BE์์๋ string์ ๊ฐ์ง๊ณ ํ๊ณ ์ถ์ ๋ฌด์ธ๊ฐ๋ฅผ ํฉ๋๋ค.
function handleNickSubmit(event) {
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send(makeMessage("nickname", input.value));
}
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);
... ์ฌ๊ธฐ์ string์ ๋ณด๋ด์ฃผ๊ณ ์์ต๋๋ค.
{"type":"new_message","payload":"gg"}
๊ฒฐ๊ณผ์ ์ผ๋ก, BE๋ ์ด string์ ๋ค์ ์ฐ๋ฆฌ์๊ฒ ๋๋ ค์ฃผ๊ณ ์์ต๋๋ค.
BE์์ ์ด string์ JS object๋ก ๋ฐ๊ฟ์ผํฉ๋๋ค.
wss.on("connection", (socket) => {
sockets.push(socket);
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
const parsed = JSON.parse(translatedMessageData);
console.log(parsed, message);
sockets.forEach(aSocket => aSocket.send(translatedMessageData));
});
});
{"type":"new_message","payload":"aa"}
์ด๊ฒ์ JS object๋ก ๋ง๋ค์ด์ผ type์ ํ์ธ ํ ์ ์์ต๋๋ค.
JSON.parse()
์ ์ฌ์ฉํฉ๋๋ค.
JSON.parse๋ string์ JS object๋ก ๋ฐ๊ฟ์ค๋๋ค.
{"type":"new_message","payload":"aa"}
{"type":"nickname","payload":"harry"}
wss.on("connection", (socket) => {
sockets.push(socket);
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", message => {
const translatedMessageData = message.toString('utf8');
const parsed = JSON.parse(translatedMessageData);
if (parsed.type === "new_message") {
sockets.forEach(aSocket => aSocket.send(parsed.payload));
}
});
});
์๋ฒ์์ ์ด๋ค ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์๋์ง ๊ตฌ๋ถํ๊ฒ ๋ฉ๋๋ค. (new_message, nickname)
๋ ๊ฐ์ง type์ ๋ฉ์์ง๋ฅผ ๋ฐ์ ์ ์๋๋ฐ, ํ๊ฐ์ง๋ new_message์ด๊ณ , ๋ค๋ฅธ ํ๊ฐ์ง๋ nickname์ ๋๋ค.
payload๋ ๋ฉ์์ง์ ๋ด๊ฒจ์๋ ์ค์ํ ์ ๋ณด๋ฅผ ๋งํฉ๋๋ค.
(๊ทธ ๋ฉ์์ง๊ฐ chat์ด๋ , nickname์ด๋ )
if๋ฌธ๋ณด๋ค switch๋ฅผ ์ฌ์ฉํฉ๋๋ค.
socket.on("message", msg => {
const translatedMessageData = msg.toString('utf8');
const message = JSON.parse(translatedMessageData);
switch (message.type) {
case "new_message":
sockets.forEach(aSocket => aSocket.send(message.payload));
case "nickname":
console.log(message.payload);
}
});
payload ์ฆ nickname์ socket์์ ๋ฃ์ด์ค์ผํฉ๋๋ค.
ํด๋น socket์ด ๋๊ตฌ์ธ์ง ์๊ณ ์ถ๊ธฐ๋๋ฌธ์
๋๋ค.
switch (message.type) {
case "new_message":
sockets.forEach(aSocket => aSocket.send(message.payload));
case "nickname":
socket["nickname"] = message.payload;
}
์ต๋ช
socket์ ๋ํด์๋ ์์
์ ํด์ผํฉ๋๋ค.
์์ง nickname์ ์ ํ์ง ์์ ์ฌ๋์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํด์ผํฉ๋๋ค.
์ด ๊ฒฝ์ฐ๋ฅผ ์ํด socket์ด ์ฐ๊ฒฐ๋ ๋,
๋ฉ์์ง๊ฐ socket์์ ์ ์ก๋๊ณ ๋ฉ์์ง์ type์ด new_message์ด๋ฉด,
message.payload ๋์ ${socket.nickname}์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
switch (message.type) {
case "new_message":
sockets.forEach(aSocket => aSocket.send(`${socket.nickname}: ${message.payload}`));
case "nickname":
socket["nickname"] = message.payload;
}
nickname ํ๋กํผํฐ๋ฅผ socket object์ ์ ์ฅํ๊ณ ์์ต๋๋ค.
socket์ 2๊ฐ๊ฐ ๋๊ณ , ํ๋๋ nickname์ด ์๋๊ฒ, ๋ค๋ฅธ ํ๋๋ ์๋ ๊ฒ์ ๋๋ค.
wss.on("connection", (socket) => {
sockets.push(socket);
socket["nickname"] = "Anon";
console.log("Connected to Browser โ
");
socket.on("close", () => console.log("Disconnected from the BROWSER โ"));
socket.on("message", msg => {
const translatedMessageData = msg.toString('utf8');
const message = JSON.parse(translatedMessageData);
switch (message.type) {
case "new_message":
sockets.forEach(aSocket => aSocket.send(`${socket.nickname}: ${message.payload}`));
case "nickname":
socket["nickname"] = message.payload;
}
});
});
... ์ด๋ถ๋ถ์ 2๋ฒ ๋ฐ๋ณตํ๊ฒ๋ฉ๋๋ค. (๋ธ๋ผ์ฐ์ 1, ๋ธ๋ผ์ฐ์ 2)
๋ฐ์ดํฐ๋ฅผ ์ฃผ๋ฉด socket์์ ์ ๋ณด๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
- ํ์ฌ๋ ๋ฉ์์ง๋ฅผ ๋ณด๋ธํ, ๊ฐ์ ๋น์์ฃผ๊ณ ์์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฉ์์ง๋ ์๋ฒ๋ก ๊ฐ๋๋ค.
- ์๋ฒ๋ก ๊ฐ ๋ฉ์์ง๋ type์ ํ์ธํฉ๋๋ค. (new_message/nickname)
- new_message๋ผ๋ฉด, ์์ ๊ณผ ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ ์กํฉ๋๋ค.
(์๊ธฐ์์ ์ ํฌํจํ ๊ณณ์ ๋ฉ์์ง๋ฅผ ๋ณด๋
๋๋ค. 2๋ฒ)
- ๋๋ฅผ ์ ์ธํ๊ณ ๋ค๋ฅธ ์ฌ๋ ๋ชจ๋์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๋ฐฉ๋ฒ
- ์ง๊ธ์ ๋ณด๋ด๋ ๋ฉ์์ง๋ฅผ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ณ ์์ง ์์ต๋๋ค.
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message", input.value));
const li = document.createElement("li");
li.innerText = `You: ${input.value}`;
messageList.append(li);
input.value = "";
}
You : Hello
๋ JS๋ก ๋ง๋ค์ด์ค ๋ฐ์ดํฐ, Anon: hello
๋ ์๋ฒ๊ฐ ๋์๊ฒ ๋ณด๋ธ ๋ฉ์์ง์
๋๋ค.
๋๋ฅผ ์ ์ธํ ๋ค๋ฅธ ๋ชจ๋์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์กํ๋ function์ ๋ง๋ญ๋๋ค.
๋๋ฒ์งธ, makeMessage function๋ ๋ฉ์์ง๋ฅผ ๋ง๋ค๊ณ , stringfy๋ฅผ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ BE์์ ๋ฉ์์ง๋ฅผ ๋ฐ์ผ๋ฉด, parseํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฉ์์ง type์ ํ์ธํฉ๋๋ค.
BE์ ๋ง์ ๊ฒ์ ๋ณด๋ด๊ณ ์ถ์ด์ object๋ฅผ ๋ณด๋ด๊ณ ์ถ๋ค๋ฉด, BE์์ JSON.stringfy๋ฅผ ์ด์ฉํด์ message๋ฅผ ๋ง๋ค์ด์ค์ผํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ FE์์๋ JSON.parse๋ฅผ ํด์ฃผ๋ ์๋ก์ด ํจ์๋ฅผ ๋ง๋ญ๋๋ค.
์๋๋ฉด ์ฌ๊ธฐ์๋ ๊ทธ๋ฅ text๋ฅผ ๋ฐ๊ณ ์๊ธฐ๋๋ฌธ์
๋๋ค.
๋๋ค๋ฅธ ๋ฉ์์ง๋ก๋ chat๋ฉ์์ง๊ฐ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ๋ฉ์์ง๋ก๋ ์ฑํ
๋ฐฉ์ ๋๊ฐ์๋ ๋์ค๋ ๋ฉ์์ง์
๋๋ค.
์ง๊ธ์ FE์ ์ค์ง ํ๊ฐ์ ๋ฉ์์ง๋ง ์์ต๋๋ค, ์ด๊ฒ์ ๊ณ์ ์ฌ์ฉํ๋ฉด
addEventListener("message")
๋ผ๋ ์ค์ด ๋ค๋ฅธ ๊ฒ์ผ๋ก ๋ฐ๋๋๋ค.
๋ธ๋ผ์ฐ์ ๊ฐ ์ฌ๋ฌ์ข ๋ฅ์ ๋ฉ์์ง๋ฅผ BE์ ๋ณด๋ด๋ ๊ฒ์ฒ๋ผ BE๋ FE์ ์ฌ๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
FE์์ parse๋ฅผ ํด์ค์ผํฉ๋๋ค.
BE์์๋ stringfy๋ฅผ ํด์ค์ผํฉ๋๋ค.