socket.io - boostcamp-2020/Project12-B-Slack-Web GitHub Wiki

socket.io ๋„์ž… ๊ณ„๊ธฐ

์ €ํฌ ํ”„๋กœ์ ํŠธ black์€ ์‹ค์‹œ๊ฐ„ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์—ฐ๋™๋  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ํ•„์š”ํ–ˆ๊ณ  ์ด๋ฅผ ์œ„ํ•ด ๋„์ž…ํ•œ ๊ฒƒ์ด socket.io์˜€์Šต๋‹ˆ๋‹ค.

socket.io๋ฅผ ํ™œ์šฉํ•˜๋ฉด์„œ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๋˜ ๋ถ€๋ถ„์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ ํ๋ฆ„, ๊ตฌ์กฐํ™”, ๊ถŒํ•œ ์ธ์ฆ ๋ฐ ์—ฐ๊ฒฐ ๋ฐฉ์‹์ด์—ˆ์Šต๋‹ˆ๋‹ค.

socket.io ํ๋ฆ„

connection event

777

black ์›น์‚ฌ์ดํŠธ์— ์ ‘์†ํ•˜๋ฉด ํ•ด๋‹น ์ ‘์†์ž๋Š” ์ž์‹ ์ด ์†ํ•œ ์ฑ„ํŒ…๋ฐฉ์˜ ์ƒˆ๋กœ์šด ๋ฉ”์‹œ์ง€๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ์ตœ์ดˆ๋กœ socket์ด connection ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์œผ๋ฉด ํ•ด๋‹น socket์„ ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์ฐธ์—ฌํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์ฑ„ํŒ…๋ฐฉ์˜ room์— joinํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํŠน์ • ๊ฐœ์ธ์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” DM ๋˜ํ•œ black์—์„œ๋Š” ๋ถ„๋ฅ˜์ƒ ์ฑ„ํŒ…๋ฐฉ์ด๋ผ room์— join์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๋‹ค๋ฅธ ์œ ์ €์— ์˜ํ•ด DM์ด ๋งŒ๋“ค์–ด์ง„ ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น DM์˜ ์ƒ์„ฑ ์—ฌ๋ถ€๋ฅผ ํŒŒ์•…ํ•ด์„œ ํ•ด๋‹น room์— joinํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด socket ์—ฐ๊ฒฐ์‹œ ์‚ฌ์šฉ์ž์˜ user id์™€ socket id๋ฅผ DB์— ์ €์žฅํ•˜๋„๋ก ํ•˜์˜€์œผ๋ฉฐ ๊ฐ™์€ ์‚ฌ์šฉ์ž์—ฌ๋„ ๋‹ค๋ฅธ ํƒญ์ธ ๊ฒฝ์šฐ socket id๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ user๋Š” ์—ฌ๋Ÿฌ socket id๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก DB์— ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•ด๋‹น socket์˜ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜๋ฉด DB์— ์ €์žฅ๋œ userid์™€ socket id๊ฐ€ ์‚ญ์ œ๋˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

message event

888

๋ฉ”์‹œ์ง€๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์œ„ํ•œ event์ž…๋‹ˆ๋‹ค.

๋ฉ”์‹œ์ง€ ์ƒ์„ฑ์„ ์œ„ํ•œ event๋ฅผ ์„œ๋ฒ„์ธก์—์„œ ๋ฐ›์œผ๋ฉด ์„œ๋ฒ„๋Š” ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ๋„ ๋ชจ๋‘ ๋ณด๋‚ด์ฃผ๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ ์„œ๋ฒ„์ธก์—์„œ emit์„ ํ•  ๋•Œ ํ•ด๋‹น ์ฑ„ํŒ…๋ฐฉ์—๋งŒ emitํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋จธ์ง€ event๋„ ์ด์™€ ๋น„์Šทํ•œ ํ๋ฆ„์œผ๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ด€๋ จํ•ด black์˜ socket.io์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด socket.io ๋ช…์„ธ์„œ๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

socket.io ํŒจํ„ด

์ „์ฒด์ ์ธ ํŒจํ„ด

์ฒ˜์Œ socket.io๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์„ ๋•Œ ๊ฐ€์žฅ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ถ€๋ถ„์€ ๊ตฌ์กฐ์˜€์Šต๋‹ˆ๋‹ค. socket.io์™€ ๊ด€๋ จํ•œ ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ์ „๋ถ€ ๋„ฃ์ž๋‹ˆ ๊ฐ€๋…์„ฑ ๋ฉด์—์„œ ์ข‹์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ event์™€ ๊ด€๋ จํ•ด์„œ ํŒŒ์ผ์„ ๋‚˜๋ˆˆ๋‹ค ํ•˜๋”๋ผ๋„ event ๋Œ€๊ธฐ ์ฝ”๋“œ โ†’ ์ฒ˜๋ฆฌ ์ฝ”๋“œ โ†’ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฝ”๋“œ๊ฐ€ ๋ชจ๋‘ ํ•œ ๊ณณ์— ํฌํ•จ๋˜๋Š” ๊ฒƒ์€ ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ๋„ ์ข‹์ง€ ์•Š์œผ๋ฆฌ๋ผ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆŒ ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ๋งŽ์€ ๊ฒ€์ƒ‰์„ ํ•ด๋ณด์•˜์œผ๋‚˜ ๋Œ€์ฒด๋กœ ๋งŽ์€ ์ฝ”๋“œ๋“ค์€ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ์ ๋Š” ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

999

์ด์™€ ๊ด€๋ จํ•ด์„œ ์Šค์Šค๋กœ ๊ตฌ์กฐํ™”๋ฅผ ํ•ด์•ผ๊ฒŸ๋‹ค๋Š” ํŒ๋‹จ์„ ํ–ˆ๊ณ  ํ‰์†Œ ์‚ฌ์šฉํ•˜๋Š” mvc๊ตฌ์กฐ์—์„œ ํžŒํŠธ๋ฅผ ์–ป์–ด์„œ ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

event์—์„œ ํ•ด๋‹น ์ด๋ฒคํŠธ๋งŒ์„ on์œผ๋กœ ๋“ฑ๋กํ•˜๋ฉฐ handler์—์„œ ์ด๋ฒคํŠธ์— ํ•„์š”ํ•œ ์„œ๋น„์Šค ํ˜ธ์ถœ ๋ฐ ์‘๋‹ต, ๊ทธ๋ฆฌ๊ณ  service์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋งŒ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์กฐํ™”๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ธ์ฆ ๋ฐ ์—ฐ๊ฒฐ ๋ฐฉ์‹

๊ถŒํ•œ ์ธ์ฆ

socket.io๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ถŒํ•œ์„ ์ธ์ฆํ•ด์„œ ๊ถŒํ•œ์ด ์žˆ๋Š” ์‚ฌ์šฉ์ž์ธ์ง€, ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๊ถŒํ•œ์„ ํ™•์ธํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์•Œ์•„์•ผํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

black์€ ๊ธฐ์กด express์—์„œ JWT์ธ์ฆ ๋ฐฉ์‹์„ ์ด์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

API๋ฅผ ํ†ตํ•œ login์„ ํ•˜๋ฉด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ›์€ JWT๋ฅผ ์ด์šฉํ•˜์—ฌ socket.io๋ฅผ ํ†ตํ•œ ํ†ต์‹ ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์˜€์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์ด๋ฃจ๊ธฐ socket.io์— middleware๋ฅผ ์žฅ์ฐฉํ•˜๊ณ  ํ•ด๋‹น middleware์—์„œ ๊ถŒํ•œ ์ธ์ฆ ๋ฐ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

//client
const socket = io(socketURL, {
  transportOptions: {
    polling: {
      extraHeaders: {
        Authorization: 'token'
      }
    }
  }
});
๊ทธ๋ฆฌ๊ณ  ์ด ๊ณผ์ •์—์„œ ํ•œ ๋ฒˆ์˜ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค.

์ตœ์ดˆ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ํš๋“ํ•œ JWT๋ฅผ socket.io์˜ extra header๋ฅผ ํ†ตํ•ด ๋ณด๋‚ด๋Š” ๊ฒƒ์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ž˜ ๋™์ž‘ํ–ˆ๊ณ  ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ์ค„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฐฉ์‹

๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ์ˆ  ์„ธ๋ฏธ๋‚˜ ๋•Œ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์œผ๊ธฐ ์œ„ํ•ด black์„ ํ™๋ณดํ•˜๋Š” ์ค‘ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

honux: "๋„คํŠธ์›Œํฌ ํƒญ์— ์—ฐ๊ฒฐ ๋ฐฉ์‹์ด polling์ด๋ž‘ websocket ๋‘˜ ๋‹ค ์žˆ๋„ค์š”? ์™œ ๋‘ ๊ฐœ ๋‹ค ์žˆ์„๊นŒ์š”? ์ด๋ ‡๊ฒŒ ๋‘๊ฐœ๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๊ฐ€ ์žˆ์„๊นŒ์š”?"

aaa

                              *polling๊ณผ websocket์ด ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.*

์ด ์งˆ๋ฌธ์„ ๋ฐ›๋Š” ์ˆœ๊ฐ„ ๋ฐ”๋กœ ๋Š๋‚€ ๊ฒƒ์€ ์ œ๋Œ€๋กœ socket.io์„ ์ดํ•ดํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š๋Š”๋‹ค์˜€์Šต๋‹ˆ๋‹ค. transport ๋ฐฉ์‹์„ ์ƒ๊ฐํ•˜์ง€ ์•Š๊ณ  default๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•œ ๋‹ต๋ณ€์„ ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด ์—ฐ๊ฒฐ ๋ฐฉ์‹์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • polling: ์ €ํฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋˜ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ‰๋ฒ”ํ•œ http request๋ฅผ ์„œ๋ฒ„๋กœ ๊ณ„์† ๋‚ ๋ ค์„œ ์ด๋ฒคํŠธ ๋‚ด์šฉ์„ ์ „๋‹ฌ๋ฐ›๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ณ„์†์ ์œผ๋กœ request๋ฅผ ๋‚ ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์— ๋ถ€๋‹ด์ด ํฐ ํŽธ์ž…๋‹ˆ๋‹ค.
  • long polling: ํด๋ผ์ด์–ธํŠธ์—์„œ ์ผ๋‹จ ์„œ๋ฒ„๋กœ http request๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด์ƒํƒœ๋กœ ๊ณ„์† ๊ธฐ๋‹ค๋ฆฌ๋‹ค๊ฐ€ ์„œ๋ฒ„์—์„œ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌํ•  ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ์ˆœ๊ฐ„ response ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•˜๋ฉด์„œ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
  • streaming: ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์„ ๋Š์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ๋ฉ”์„ธ์ง€๋ฅผ ๊ณ„์† ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ปค๋„ฅ์…˜์„ ๋งบ๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ถ€๋‹ด์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.
  • websocket

์›น ์†Œ์ผ“์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์˜ ์ „์ด์ค‘ ํ†ต์‹ ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ํ†ต์‹  ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฐฉ์‹์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1.  ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์— ์ „์ด์ค‘ ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ HTTP UPGRADE ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์›น ์†Œ์ผ“ ํ”„๋กœํ† ์ฝœ ํ•ธ๋“œ ์‰์ดํฌ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
2. ์„œ๋ฒ„๊ฐ€ ์ปค๋„ฅ์…˜์„ UPGRADE ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ,  HTTP 101 ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ํ•ธ๋“œ ์‰์ดํฌ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ณ , ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด์˜ ์ปค๋„ฅ์…˜์„ ์›น ์†Œ์ผ“ ํ”„๋กœํ† ์ฝœ๋กœ UPGRADE ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์˜ HTTP 101 ์‘๋‹ต์ด ์ „๋‹ฌ๋˜๋Š” ์ˆœ๊ฐ„, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด์˜ ์ปค๋„ฅ์…˜์€ HTTP ํ”„๋กœํ† ์ฝœ์ด๋ผ๊ณ  ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ์˜ค ์ด์ˆœ๊ฐ„ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.
3. ์›น ์†Œ์ผ“์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๋Š” ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ปค๋„ฅ์…˜์„ ๋Š๋Š” ์š”์ฒญ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰ ์œ„์— ์„ค๋ช…ํ•œ ๋‹ค๋ฅธ ๋‹จ๋ฐฉํ–ฅํ†ต์‹ ์„ ์–ด๋–ป๊ฒŒ๋“  ์ด์šฉํ•ด์„œ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•œ ๋ฐฉ์‹์—์„œ ๋ฒ—์–ด๋‚˜ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์—ฐ๊ฒฐ๋ฐฉ์‹์—์„œ websocket์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒƒ์€ ์†๋„์™€ ๋ถ€ํ•˜๋ฉด์—์„œ ๋‹น์—ฐํ•˜๊ฒŒ ๋ณด์˜€๊ณ , ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ polling ๋ฐฉ์‹์—์„œ websocket์œผ๋กœ ์—ฐ๊ฒฐ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ „ํ™˜์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

// client
const socket = io(socketURL, {
  transports:['websocket','polling']
  transportOptions: {
    polling: {
      extraHeaders: {
        Authorization: 'token'
      }
    },
		websocket: {
			extraHeaders: {
        Authorization: 'token'			
			}
		}
  }
});

๊ทธ๋Ÿฌ๋‚˜ ์ด ์ฝ”๋“œ์—์„œ socket.io ๋Š” ์ƒ๊ฐ๋Œ€๋กœ ๋™์ž‘๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด์˜ extraheader๋กœ Authorization์„ ๋ถ™์—ฌ์คฌ์—ˆ๋Š”๋ฐ ์ด๋Š” ๋งค๋ฒˆ request๊ฐ€ ๋ณด๋‚ด์ง€๋Š” polling ๋ฐฉ์‹์—์„œ๋งŒ ์ง€์›๋˜๋Š” ๋ฐฉ์‹์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋กœ์ง์„ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ๊ถŒํ•œ ์ธ์ฆ

websocket์—์„œ ๊ถŒํ•œ ์ธ์ฆ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒˆ๋กญ๊ฒŒ ๋„์ž…ํ•œ ๋ฐฉ์‹์€ query string์ด์˜€์Šต๋‹ˆ๋‹ค. query string์œผ๋กœ ํ† ํฐ์„ ์ „๋‹ฌ๋ฐ›์œผ๋ฉด middleware์—์„œ websocket handshake๋•Œ ๋ฐ›์€ query๋ฅผ ์ด์šฉํ•ด ์œ ํšจ ๊ฒ€์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

//client
const socket = io(socketURL, {
  query: { token: window.localStorage.getItem('token') },
  transports: ['websocket', 'polling']
});
//server socket middleware
const jwtMiddleware = (io) => {
  const wrap = (middleware) => (socket, next) => {
    const { request } = socket;
    const { token } = socket.handshake.query;
    request.headers.authorization = token;
    middleware(request, {}, next);
  };
  io.use(wrap(passport.authenticate('jwt', { session: false })));
};

์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•จ์œผ๋กœ์จ ์„ฑ๊ณต์ ์œผ๋กœ websocket์„ ์ด์šฉํ•œ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

bbb

์„œ๋ฒ„์— ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” polling ๋ฐฉ์‹์ด network tab์—์„œ ์‚ฌ๋ผ์ง€๊ณ  websocket๋งŒ์œผ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋Š๋‚€ ์ 

ํ•ด๋‹น ๊ธฐ์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•˜๊ฒŒ ๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” socket.io์ด์—ˆ์Šต๋‹ˆ๋‹ค.

(๋‚˜๋จธ์ง€ ํ•˜๋‚˜๋Š” ๋„์ปค ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์ž…๋‹ˆ๋‹ค.)

๋ฐฑ์—”๋“œ, ๋„คํŠธ์›Œํฌ์— ํ‰์†Œ ๊ด€์‹ฌ์ด ๋งŽ์•˜์œผ๋ฉฐ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š”๋‹ค๋Š” ๊ฒƒ์ด ํ™œ์šฉํ•ด๋ณธ ๊ฒฝํ—˜์ด ์—†์ง€๋งŒ ๋ง‰์—ฐํžˆ ์ด๊ฑฐ๋ผ๋ฉด ๋ถ„๋ช… ์žฌ๋ฐŒ๊ฒ ๋‹ค!๋ผ๋Š” ํ™•์‹ ์ด ๋“ค์–ด์„œ ์ฃผ์ €์—†์ด ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•ด์„œ 1์ˆœ์œ„๋กœ ์ง€๋งํ–ˆ๋˜ ๊ธฐ์–ต์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ socket.io๋ฅผ ์ „๋‹ดํ•˜๊ฒŒ ๋˜๋ฉด์„œ ๋‹คํ–‰ํžˆ๋„ ๊ธฐ๋Œ€์™€ ๊ฐ™์ด ์žฌ๋ฐŒ๋Š” ์ž‘์—…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋กœ ์ธํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์—์„œ ์žฌ๋ฏธ๋ฅผ ๋Š๋‚„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์–ธ์ œ๋‚˜ ์ž‘์—…์„ ํ•˜๋ฉด์„œ ๋ฐ˜์„ฑ๊ณผ ํ”ผ๋“œ๋ฐฑ์„ ํ•˜๊ฒŒ ๋˜๋Š” ๊ณผ์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ง€์‹๊ณผ ์ดํ•ด๊ฐ€ ์ค‘์š”ํ•˜๋‹ค

์ฒ˜์Œ socket.io๋ฅผ ํ™œ์šฉํ•˜๋ฉด์„œ ๋ง‰์—ฐํžˆ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ๋”ฐ๋ผํ•˜๋‹ˆ๊น ๋˜๋„ค?๋ผ๋Š” ๊ณผ์ •์œผ๋กœ ์‹œ์ž‘์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋„ socket.io๋ฅผ ํ™œ์šฉํ•œ ๊ฐœ๋ฐœ์€ ๊ทธ๋ฆฌ ์–ด๋ ต์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ดํ›„ ์ง„ํ–‰์„ ํ•˜๋ฉด์„œ ๋™์ž‘์€ ํ•˜์ง€๋งŒ ๋ถ€์ ์ ˆํ•œ ์—ฐ๊ฒฐ ๋ฐฉ์‹์—์„œ ๊ณต๋ถ€์™€ ์ดํ•ด๊ฐ€ ํ•„์š”ํ–ˆ๊ณ , handshake, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ websocket์ด ์ง€์›๋˜๋ฉด 101 ์‘๋‹ต์ฝ”๋“œ๋ฅผ ๋ณด๋‚ด์„œ websocket์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•˜๋Š” ๋“ฑ์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ํ•ด์•ผํ–ˆ๊ณ  ์ด ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉด์„œ ์ƒ๊ฐ์˜ ํ๋ฆ„์„ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค.

์ž˜ ์ง€์›ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๋„ ์—ญ์‹œ ์•Œ๊ณ  ์จ์•ผ ํ•˜๋Š”๊ตฌ๋‚˜ โ†’ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ •๋…ํ•  ํ•„์š”๊ฐ€ ์žˆ๋„ค โ†’ ์ด ๋ฌธ์„œ๋ฅผ ์ •๋…ํ•˜๋ฉด์„œ ์ดํ•ด๋ฅผ ํ•˜๋ ค๋ฉด ๊ธฐ๋ณธ์ ์ธ cs์ง€์‹์ด ๋ฐ”ํƒ•์ด ๋˜์–ด์•ผ๊ฒ ๊ตฌ๋‚˜

์ด๋Ÿฌํ•œ ์ •๋ง ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ์ง€๋งŒ ๋ฐ›์•„๋“ค์ด๊ณ ๋งŒ ์žˆ๋˜ ํ๋ฆ„์„ ์ง์ ‘ ๊นจ๋‹ฌ์„ ์ˆ˜ ์žˆ์—ˆ๋˜ ์†Œ์ค‘ํ•œ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ์—ญ์‹œ ์žฌ๋ฐŒ๋‹ค

๊ธฐ๋ณธ์ ์ธ ์ง€์‹์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •์ด ํ•„์š”ํ–ˆ์Œ์—๋„ ๊ทธ ๊ณผ์ •์€ ์žฌ๋ฐŒ์—ˆ์Šต๋‹ˆ๋‹ค. ํ‰์†Œ ํด๋ผ์šฐ๋“œ์— ํฅ๋ฏธ๋ฅผ ๊ฐ€์ ธ์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ์ข‹์•„ํ•ด์„œ์ธ์ง€ ์ดํ•ด๋„ ๋‚˜๋ฆ„ ์ž˜ ๋๊ณ  ์ƒˆ๋กญ๊ฒŒ ์•Œ์•„๊ฐ€๋Š” ๊ณผ์ •์ด ์ข‹์•˜๊ณ  ์›๋ฆฌ์™€ ๋™์ž‘์„ ์ดํ•ดํ•˜๋ฉด์„œ ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ณผ์ • ๋˜ํ•œ ๋„ˆ๋ฌด ์ข‹์•˜์Šต๋‹ˆ๋‹ค.