๐Ÿ’ป ์คŒ ํด๋ก  ์ฑŒ๋ฆฐ์ง€ DAY+02

yhwaยท2023๋…„ 2์›” 20์ผ
0
post-thumbnail

๐Ÿ“ ์คŒ ํด๋ก ์ฝ”๋”ฉ: From #1.0 to #1.9

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜์—ฌ ๋ณด๋‚ด๊ธฐ & ๋ฐ›๊ธฐ ๊ธฐ๋Šฅ์„ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค.
๋‹‰๋„ค์ž„ ์ถ”๊ฐ€ํ•˜๊ธฐ -> ์ฑ„ํŒ…์— ์ฐธ๊ฐ€ํ• ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ๋‹‰๋„ค์ž„์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฑ„ํŒ…๋ฐฉ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
์ฑ„ํŒ…๊ฒฝํ—˜์„ ๋” ์ข‹๊ฒŒ ํ•ด์ฃผ๋Š” eventํ™œ์šฉ์„ ํ•ฉ๋‹ˆ๋‹ค.
"OO๋‹˜์ด ์ž…์žฅ/ํ‡ด์žฅ ํ–ˆ์Šต๋‹ˆ๋‹ค." / ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…๋ฐฉ ์ธ์›์ˆ˜
์ต๋ช… > ๋‹‰๋„ค์ž„ ์ถ”๊ฐ€ > ์ฑ„ํŒ…๋ฐฉ ์ปจ์…‰ ์ •ํ•˜๊ธฐ
์„œ๋ฒ„์˜ ๋ฐฉ์ด ๋ช‡๊ฐœ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ

HTTP์™€ WebSockets

- http์™€ websockets๋Š” ๋‘˜๋‹ค protocol์ž…๋‹ˆ๋‹ค.
- ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ http๊ฐ€ stateless๋ผ๋Š” ์ ์ž…๋‹ˆ๋‹ค.
- ์›น์†Œ์ผ“์€ ํ•œ๋ฒˆ ์—ฐ๊ฒฐ์ด ์„ฑ๋ฆฝ๋˜๋ฉด, ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ์ด ์ƒ๊น๋‹ˆ๋‹ค.
- ์›น์†Œ์ผ“์€ request-reponse๊ฐ™์€๊ฒŒ ํ•„์š”์—†์Šต๋‹ˆ๋‹ค.

HTTP Protocol

- ๋ชจ๋“  ์„œ๋ฒ„๋“ค์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
- ์œ ์ €๊ฐ€ 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("/"));

WebSocket Protocol

- ์›น์†Œ์ผ“์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, 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๊ฐœ์˜ ์„œ๋ฒ„ ์‚ฌ์ด์—์„œ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

NodeJS๋กœ WebSocket ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

- 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 ์‚ฌ์šฉํ•˜๊ธฐ

ws ์„ค์น˜ํ•˜๊ธฐ

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์„œ๋ฒ„๊ฐ€ ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ws์—ฐ๊ฒฐ๋กœ ๋ธŒ๋ผ์šฐ์ €์™€ ๋ฉ”์‹œ์ง€ ์ฃผ๊ณ  ๋ฐ›๊ธฐ

- WebSocket Event

connection(์—ฐ๊ฒฐ)์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

- ws๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ backend์™€ frontend ์‚ฌ์ด์—์„œ ์—ฐ๊ฒฐ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
- FE์—์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฏธ webSocket ํด๋ผ์ด์–ธํŠธ์— 
๋Œ€ํ•œimplementation์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
- webSocket์„ ์ด์šฉํ•ด BE์™€ JS๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ์•„๋ฌด๊ฒƒ๋„ ์ค€๋น„ํ•  ํ•„์š” ์—†์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

BE์—์„œ์˜ webSocket

- 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 });

๋ธŒ๋ผ์šฐ์ €์—์„œ event๋ž€ ๋ฌด์—‡์ผ๊นŒ

- 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์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

connection์„ ๋งŒ๋“ค๊ธฐ์œ„ํ•œ (FE)app.js ์ˆ˜์ •

- 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๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FE์˜ socket๊ณผ BE์˜ socket์˜ ์ฐจ์ด

 - server.js์˜ socket์€ ์—ฐ๊ฒฐ๋˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
 - app.js์˜ socket์€ ์„œ๋ฒ„๋กœ์˜ ์—ฐ๊ฒฐ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
 

webSocket์œผ๋กœ ๋ฉ”์‹œ์ง€ ์ฃผ๊ณ ๋ฐ›๊ธฐ

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

Pug ํ™”๋ฉด ์ˆ˜์ •

- 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);
    });

});

FE1 -> BE -> FE2 ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ

- ์„œ๋ฒ„๊ฐ€ 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);
});

๋ฉ”์‹œ์ง€ ํƒ€์ž… ๊ตฌ๋ถ„ํ•˜๊ธฐ (chatting, nickName)

- ๋Œ€ํ™”๋Š” ์ต๋ช…์œผ๋กœ ์ง„ํ–‰๋˜๋ฉฐ ์„œ๋กœ์˜ ์†Œ์ผ“์„ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” 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๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค์‹œ ์ „์†กํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

BE์—์„œ object ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  JS๋กœ ์“ธ์ˆ˜์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ฐ”๊พธ๊ธฐ

- 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๋ฅผ ํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.

profile
๐Ÿ“Œ FE ๊ณต๋ถ€ ์ •๋ฆฌ ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€