Cheerp, WebRTC ๋ฐ Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C++์—์„œ ์›น์œผ๋กœ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„ ํฌํŒ…

์†Œ๊ฐœ

์šฐ๋ฆฌ ํšŒ์‚ฌ ๊ธฐ๋Œ€์–ด ๊ธฐ์ˆ  ๊ธฐ์กด ๋ฐ์Šคํฌํ†ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์›น์œผ๋กœ ํฌํŒ…ํ•˜๊ธฐ ์œ„ํ•œ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ C++ ์ปดํŒŒ์ผ๋Ÿฌ ์‘์› WebAssembly์™€ JavaScript์˜ ์กฐํ•ฉ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ๋ธŒ๋ผ์šฐ์ € ์ƒํ˜ธ ์ž‘์šฉ, ๊ณ ์„ฑ๋Šฅ.

๊ทธ ์ ์šฉ ์‚ฌ๋ก€๋กœ์„œ ์šฐ๋ฆฌ๋Š” ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„์„ ์›น์œผ๋กœ ํฌํŒ…ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๊ณ  ์ด๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. Teeworlds. Teeworlds๋Š” ์ž‘์ง€๋งŒ ํ™œ๋™์ ์ธ ํ”Œ๋ ˆ์ด์–ด ์ปค๋ฎค๋‹ˆํ‹ฐ(์ € ํฌํ•จ!)๊ฐ€ ์žˆ๋Š” ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด XNUMXD ๋ณต๊ณ ํ’ ๊ฒŒ์ž„์ž…๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ๋œ ๋ฆฌ์†Œ์Šค์™€ CPU ๋ฐ GPU ์š”๊ตฌ ์‚ฌํ•ญ ์ธก๋ฉด์—์„œ ๋ชจ๋‘ ์ž‘์œผ๋ฏ€๋กœ ์ด์ƒ์ ์ธ ํ›„๋ณด์ž…๋‹ˆ๋‹ค.

Cheerp, WebRTC ๋ฐ Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C++์—์„œ ์›น์œผ๋กœ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„ ํฌํŒ…
Teeworlds ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰

์šฐ๋ฆฌ๋Š” ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ—˜ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์ฝ”๋“œ๋ฅผ ์›น์œผ๋กœ ํฌํŒ…ํ•˜๊ธฐ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ ์†”๋ฃจ์…˜. ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

  • XMLHttp์š”์ฒญ/๊ฐ€์ ธ์˜ค๊ธฐ, ๋„คํŠธ์›Œํฌ ๋ถ€๋ถ„์ด HTTP ์š”์ฒญ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ, ๋˜๋Š”
  • WebSocket์„.

๋‘ ์†”๋ฃจ์…˜ ๋ชจ๋‘ ์„œ๋ฒ„ ์ธก์—์„œ ์„œ๋ฒ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•ด์•ผ ํ•˜๋ฉฐ ๋‘˜ ๋‹ค ์ „์†ก ํ”„๋กœํ† ์ฝœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. UDP. ์ด๋Š” ํ”„๋กœํ† ์ฝœ ํŒจํ‚ท์˜ ์ „๋‹ฌ ๋ฐ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋ฏ€๋กœ ํ™”์ƒ ํšŒ์˜ ์†Œํ”„ํŠธ์›จ์–ด ๋ฐ ๊ฒŒ์ž„๊ณผ ๊ฐ™์€ ์‹ค์‹œ๊ฐ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. TCP ๋‚ฎ์€ ๋ ˆ์ดํ„ด์‹œ๋ฅผ ๋ฐฉํ•ดํ•˜๋Š” ์š”์†Œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. WebRTC๊ฐ€.

RTC๋ฐ์ดํ„ฐ ์ฑ„๋„ ์ด๋Š” ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ „์†ก๊ณผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ „์†ก์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋ฉฐ(ํ›„์ž์˜ ๊ฒฝ์šฐ ๊ฐ€๋Šฅํ•  ๋•Œ๋งˆ๋‹ค UDP๋ฅผ ์ „์†ก ํ”„๋กœํ† ์ฝœ๋กœ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•จ) ์›๊ฒฉ ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ € ๊ฐ„์— ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์„œ๋ฒ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ธŒ๋ผ์šฐ์ €๋กœ ํฌํŒ…ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค!

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

์ด์ƒ์ ์œผ๋กœ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ WebRTC๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” UDP ์†Œ์ผ“ ์ธํ„ฐํŽ˜์ด์Šค์— ์ตœ๋Œ€ํ•œ ๊ฐ€๊นŒ์šด ๋„คํŠธ์›Œํฌ API๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์— ๋ณต์žกํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ ๋„ WebRTC๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ด๋ฅผ ๊ฐ€๋Šฅํ•œ ํ•œ ์ ๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค).

์ตœ์†Œ WebRTC

WebRTC๋Š” ์˜ค๋””์˜ค, ๋น„๋””์˜ค ๋ฐ ์ž„์˜ ๋ฐ์ดํ„ฐ์˜ PXNUMXP ์ „์†ก์„ ์ œ๊ณตํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” API ์„ธํŠธ์ž…๋‹ˆ๋‹ค.

ํ”ผ์–ด ๊ฐ„์˜ ์—ฐ๊ฒฐ์€ ICE๋ผ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด STUN ๋ฐ/๋˜๋Š” TURN ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ (ํ•œ์ชฝ ๋˜๋Š” ์–‘์ชฝ์— NAT๊ฐ€ ์žˆ๋”๋ผ๋„) ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ํ”ผ์–ด๋Š” SDP ํ”„๋กœํ† ์ฝœ์˜ ์ œ์•ˆ ๋ฐ ์‘๋‹ต์„ ํ†ตํ•ด ICE ์ •๋ณด ๋ฐ ์ฑ„๋„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ตํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์šฐ์™€! ํ•œ ๋ฒˆ์— ๋ช‡ ๊ฐœ์˜ ์•ฝ์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ์šฉ์–ด์˜ ์˜๋ฏธ๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  • NAT์šฉ ์„ธ์…˜ ์ˆœํšŒ ์œ ํ‹ธ๋ฆฌํ‹ฐ (์ถฉ๊ฒฉ) โ€” NAT๋ฅผ ์šฐํšŒํ•˜๊ณ  ํ˜ธ์ŠคํŠธ์™€ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ์Œ(IP, ํฌํŠธ)์„ ์–ป๊ธฐ ์œ„ํ•œ ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด ๋™๋ฃŒ๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • NAT ์ฃผ๋ณ€์˜ ๋ฆด๋ ˆ์ด๋ฅผ ์‚ฌ์šฉํ•œ ์ˆœํšŒ (ํšŒ์ „) NAT ํ†ต๊ณผ์—๋„ ์‚ฌ์šฉ๋˜์ง€๋งŒ ๋‘ ํ”ผ์–ด ๋ชจ๋‘์—๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ์ด๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. STUN๋ณด๋‹ค ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ถ”๊ฐ€๋˜๊ณ  ๊ตฌํ˜„ ๋น„์šฉ์ด ๋” ๋†’์ง€๋งŒ(์ „์ฒด ํ†ต์‹  ์„ธ์…˜์— ๊ฑธ์ณ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์—) ๋•Œ๋กœ๋Š” ์ด๊ฒƒ์ด ์œ ์ผํ•œ ์˜ต์…˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์ปค๋„ฅํ‹ฐ๋น„ํ‹ฐ ๊ตฌ์ถ• (ICE) ํ”ผ์–ด๋ฅผ ์ง์ ‘ ์—ฐ๊ฒฐํ•˜์—ฌ ์–ป์€ ์ •๋ณด์™€ ๋‹ค์ˆ˜์˜ STUN ๋ฐ TURN ์„œ๋ฒ„์—์„œ ์ˆ˜์‹ ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‘ ํ”ผ์–ด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์„ธ์…˜ ์„ค๋ช… ํ”„๋กœํ† ์ฝœ (SDP) ICE ํ›„๋ณด, ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ์ฝ”๋ฑ(์˜ค๋””์˜ค/๋น„๋””์˜ค ์ฑ„๋„์˜ ๊ฒฝ์šฐ) ๋“ฑ๊ณผ ๊ฐ™์€ ์—ฐ๊ฒฐ ์ฑ„๋„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ํ˜•์‹์ž…๋‹ˆ๋‹ค. ํ”ผ์–ด ์ค‘ ํ•˜๋‚˜๋Š” SDP Offer๋ฅผ ๋ณด๋‚ด๊ณ  ๋‘ ๋ฒˆ์งธ๋Š” SDP Answer๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ... ๊ทธ ํ›„ ์ฑ„๋„์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ํ”ผ์–ด๋Š” STUN ๋ฐ TURN ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์ด๋ฅผ ์„œ๋กœ ๊ตํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์•„์ง ์ง์ ‘ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•˜๋ ค๋ฉด ์‹ ํ˜ธ ์„œ๋ฒ„๋ผ๋Š” ๋Œ€์—ญ ์™ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹ ํ˜ธ ์„œ๋ฒ„๋Š” ์œ ์ผํ•œ ์ž‘์—…์ด ํ•ธ๋“œ์…ฐ์ดํฌ ๋‹จ๊ณ„์—์„œ ํ”ผ์–ด ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ๋งค์šฐ ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ ์ฐธ์กฐ).

Cheerp, WebRTC ๋ฐ Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C++์—์„œ ์›น์œผ๋กœ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„ ํฌํŒ…
๋‹จ์ˆœํ™”๋œ WebRTC ํ•ธ๋“œ์…ฐ์ดํฌ ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

Teeworlds ๋„คํŠธ์›Œํฌ ๋ชจ๋ธ ๊ฐœ์š”

Teeworlds ๋„คํŠธ์›Œํฌ ์•„ํ‚คํ…์ฒ˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐ€์ง€ ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๊ฒŒ์ž„๋งŒ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ์—ฌ๋Ÿฌ ์„œ๋ฒ„ ์ค‘ ํ•˜๋‚˜์— ์—ฐ๊ฒฐํ•˜์—ฌ ๊ฒŒ์ž„์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  • ๊ฒŒ์ž„ ๋‚ด ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ „์†ก์€ ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.
  • ๊ฒŒ์ž„ ํด๋ผ์ด์–ธํŠธ์— ํ‘œ์‹œ๋˜๋Š” ๋ชจ๋“  ๊ณต์šฉ ์„œ๋ฒ„ ๋ชฉ๋ก์„ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ˆ˜ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ์œ„ํ•ด WebRTC๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๊ฒŒ์ž„์˜ ์„œ๋ฒ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ์—๊ฒŒ ์ข‹์€ ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค...

์„œ๋ฒ„๋ฅผ ์—†์• ์„ธ์š”

์„œ๋ฒ„ ๋กœ์ง์ด ์—†๋‹ค๋Š” ์ ์€ ์ข‹์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. Github ํŽ˜์ด์ง€๋‚˜ Cloudflare ๋’ค์˜ ์ž์ฒด ํ•˜๋“œ์›จ์–ด์— ์ •์  ์ฝ˜ํ…์ธ ๋กœ ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฌด๋ฃŒ๋กœ ๋น ๋ฅธ ๋‹ค์šด๋กœ๋“œ์™€ ๋†’์€ ๊ฐ€๋™ ์‹œ๊ฐ„์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ๋“ค์„ ์žŠ์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ์œผ๋ฉฐ ์šด์ด ์ข‹๊ณ  ๊ฒŒ์ž„์ด ์ธ๊ธฐ๋ฅผ ์–ป๊ฒŒ ๋œ๋‹ค๋ฉด ์ธํ”„๋ผ๋ฅผ ํ˜„๋Œ€ํ™”ํ•  ํ•„์š”๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹œ์Šคํ…œ์ด ์ž‘๋™ํ•˜๋ ค๋ฉด ์—ฌ์ „ํžˆ ์™ธ๋ถ€ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ•˜๋‚˜ ์ด์ƒ์˜ STUN ์„œ๋ฒ„: ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฌด๋ฃŒ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ตœ์†Œ ํ•˜๋‚˜์˜ TURN ์„œ๋ฒ„: ์—ฌ๊ธฐ์—๋Š” ๋ฌด๋ฃŒ ์˜ต์…˜์ด ์—†์œผ๋ฏ€๋กœ ์ž์ฒด์ ์œผ๋กœ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ์„œ๋น„์Šค ๋น„์šฉ์„ ์ง€๋ถˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ STUN ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ(๋ฐ ์ง„์ •ํ•œ p2p ์ œ๊ณต) ๋Œ€์ฒด ์˜ต์…˜์œผ๋กœ TURN์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์‹œ๊ทธ๋„๋ง ์„œ๋ฒ„: ๋‹ค๋ฅธ ๋‘ ๊ฐ€์ง€ ์ธก๋ฉด๊ณผ ๋‹ฌ๋ฆฌ ์‹œ๊ทธ๋„๋ง์€ ํ‘œ์ค€ํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ๊ทธ๋„๋ง ์„œ๋ฒ„๊ฐ€ ์‹ค์ œ๋กœ ๋‹ด๋‹นํ•˜๋Š” ์ผ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•˜๊ธฐ ์ „์— ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Teeworlds ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„: ๋‹ค๋ฅธ ์„œ๋ฒ„์—์„œ ์ž์‹ ์˜ ์กด์žฌ๋ฅผ ์•Œ๋ฆฌ๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ณต์šฉ ์„œ๋ฒ„๋ฅผ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ(ํด๋ผ์ด์–ธํŠธ๋Š” ํ•ญ์ƒ ์ˆ˜๋™์œผ๋กœ ์•Œ๊ณ  ์žˆ๋Š” ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ) ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ž„์˜์˜ ์‚ฌ๋žŒ๋“ค๊ณผ ๊ฒŒ์ž„์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” Google์˜ ๋ฌด๋ฃŒ STUN ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๊ณ  ํ•˜๋‚˜์˜ TURN ์„œ๋ฒ„๋ฅผ ์ง์ ‘ ๋ฐฐํฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•œ ๋งˆ์ง€๋ง‰ ๋‘ ์ ์— ๋Œ€ํ•ด ์ค‘ํฌ ๊ธฐ์ง€:

  • Teeworlds ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋Š” ๊ฐ ํ™œ์„ฑ ์„œ๋ฒ„์˜ ์ •๋ณด(์ด๋ฆ„, IP, ์ง€๋„, ๋ชจ๋“œ ๋“ฑ)๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐœ์ฒด ๋ชฉ๋ก์œผ๋กœ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์ž์ฒด ๊ฐœ์ฒด๋ฅผ ๊ฒŒ์‹œํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•˜๋ฉฐ ํด๋ผ์ด์–ธํŠธ๋Š” ์ „์ฒด ๋ชฉ๋ก์„ ๊ฐ€์ ธ์™€ ํ”Œ๋ ˆ์ด์–ด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์„œ๋ฒ„๋ฅผ ํด๋ฆญํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฐ”๋กœ ๊ฒŒ์ž„์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™ˆ ํŽ˜์ด์ง€์— ๋ชฉ๋ก์„ HTML๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์‹ ํ˜ธ๋Š” ๋‹ค์Œ ์„น์…˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ์†Œ์ผ“ ๊ตฌํ˜„๊ณผ ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Cheerp, WebRTC ๋ฐ Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C++์—์„œ ์›น์œผ๋กœ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„ ํฌํŒ…
๊ฒŒ์ž„ ๋‚ด๋ถ€ ๋ฐ ํ™ˆํŽ˜์ด์ง€์˜ ์„œ๋ฒ„ ๋ชฉ๋ก

์†Œ์ผ“ ๊ตฌํ˜„

์šฐ๋ฆฌ๋Š” ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ํšŸ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด Posix UDP ์†Œ์ผ“์— ์ตœ๋Œ€ํ•œ ๊ฐ€๊นŒ์šด API๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์šฐ๋ฆฌ๋Š” ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•œ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ตฌํ˜„ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์‹ค์ œ ๋ผ์šฐํŒ…์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”ผ์–ด๋Š” ํŠน์ • Firebase ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ธ์Šคํ„ด์Šค์™€ ์—ฐ๊ฒฐ๋œ ๋™์ผํ•œ "๊ฐ€์ƒ LAN"์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ณ ์œ ํ•œ IP ์ฃผ์†Œ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ณ ์œ ํ•œ Firebase ํ‚ค ๊ฐ’(๋„๋ฉ”์ธ ์ด๋ฆ„๊ณผ ์œ ์‚ฌ)์€ ํ”ผ์–ด๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„ํ•˜๋ฉฐ, ๊ฐ ํ”ผ์–ด๋Š” ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๊ฐ ํ‚ค์— ๋กœ์ปฌ๋กœ "๊ฐ€์งœ" IP ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒฐ์ฝ” ์‰ฝ์ง€ ์•Š์€ ์ž‘์—…์ธ ๊ธ€๋กœ๋ฒŒ IP ์ฃผ์†Œ ํ• ๋‹น์˜ ํ•„์š”์„ฑ์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ตœ์†Œ API๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// Create and destroy a socket
int socket();
int close(int fd);
// Bind a socket to a port, and publish it on Firebase
int bind(int fd, AddrInfo* addr);
// Send a packet. This lazily create a WebRTC connection to the 
// peer when necessary
int sendto(int fd, uint8_t* buf, int len, const AddrInfo* addr);
// Receive the packets destined to this socket
int recvfrom(int fd, uint8_t* buf, int len, AddrInfo* addr);
// Be notified when new packets arrived
int recvCallback(Callback cb);
// Obtain a local ip address for this peer key
uint32_t resolve(client::String* key);
// Get the peer key for this ip
String* reverseResolve(uint32_t addr);
// Get the local peer key
String* local_key();
// Initialize the library with the given Firebase database and 
// WebRTc connection options
void init(client::FirebaseConfig* fb, client::RTCConfiguration* ice);

API๋Š” ๊ฐ„๋‹จํ•˜๊ณ  Posix Sockets API์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ ๋กœ๊น…, ๋กœ์ปฌ IP ํ• ๋‹น ๋ฐ ์ง€์—ฐ ์—ฐ๊ฒฐ.

์ฝœ๋ฐฑ ๋“ฑ๋ก

์›๋ณธ ํ”„๋กœ๊ทธ๋žจ์ด ๋น„์ฐจ๋‹จ I/O๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ํ”„๋กœ๊ทธ๋žจ(JavaScript ๋˜๋Š” WebAssembly)์—์„œ ์ˆจ๊ฒจ์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

while(running) {
  select(...); // wait for I/O events
  while(true) {
    int r = readfrom(...); // try to read
    if (r < 0 && errno == EWOULDBLOCK) // no more data available
      break;
    ...
  }
  ...
}

์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ˆจ๊ฒจ์ ธ ์žˆ์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

auto cb = []() { // this will be called when new data is available
  while(true) {
    int r = readfrom(...); // try to read
    if (r < 0 && errno == EWOULDBLOCK) // no more data available
      break;
    ...
  }
  ...
};
recvCallback(cb); // register the callback

๋กœ์ปฌ IP ํ• ๋‹น

"๋„คํŠธ์›Œํฌ"์˜ ๋…ธ๋“œ ID๋Š” IP ์ฃผ์†Œ๊ฐ€ ์•„๋‹ˆ๋ผ Firebase ํ‚ค์ž…๋‹ˆ๋‹ค(๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค: -LmEC50PYZLCiCP-vqde ).

์ด๋Š” IP๋ฅผ ํ• ๋‹นํ•˜๊ณ  ๊ณ ์œ ์„ฑ์„ ํ™•์ธ(ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ํ›„ ์ฒ˜๋ฆฌ)ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํŽธ๋ฆฌํ•˜์ง€๋งŒ, ์ˆซ์ž ๊ฐ’์œผ๋กœ ํ”ผ์–ด๋ฅผ ์‹๋ณ„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฐ”๋กœ ๊ธฐ๋Šฅ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ชฉ์ ์ž…๋‹ˆ๋‹ค. resolve ะธ reverseResolve: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์–ด๋–ป๊ฒŒ๋“  (์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋˜๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด) ํ‚ค์˜ ๋ฌธ์ž์—ด ๊ฐ’์„ ์ˆ˜์‹ ํ•˜๊ณ  ๋‚ด๋ถ€ ์‚ฌ์šฉ์„ ์œ„ํ•ด ์ด๋ฅผ IP ์ฃผ์†Œ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๋„ ๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ๋ฌธ์ž์—ด ๋Œ€์‹  ์ด ๊ฐ’์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ด๋Š” DNS ์กฐํšŒ์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋กœ์ปฌ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, IP ์ฃผ์†Œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์— ๊ณต์œ ๋  ์ˆ˜ ์—†์œผ๋ฉฐ, ์ผ์ข…์˜ ์ „์—ญ ์‹๋ณ„์ž๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฒŒ์œผ๋ฅธ ์—ฐ๊ฒฐ

UDP์—๋Š” ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•˜์ง€ ์•Š์ง€๋งŒ ์•ž์„œ ์‚ดํŽด๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ WebRTC๋Š” ๋‘ ํ”ผ์–ด ๊ฐ„์— ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์˜ค๋žœ ์—ฐ๊ฒฐ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋™์ผํ•œ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๋ฅผ ์ œ๊ณตํ•˜๋ ค๋ฉด (sendto/recvfrom ์‚ฌ์ „ ์—ฐ๊ฒฐ์ด ์—†๋Š” ์ž„์˜์˜ ํ”ผ์–ด์™€ ํ•จ๊ป˜) API ๋‚ด์—์„œ "์ง€์—ฐ"(์ง€์—ฐ) ์—ฐ๊ฒฐ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” UDP๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ โ€œ์„œ๋ฒ„โ€์™€ โ€œํด๋ผ์ด์–ธํŠธโ€ ๊ฐ„์˜ ์ผ๋ฐ˜์ ์ธ ํ†ต์‹  ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ์ผ์ด๋ฉฐ, ์šฐ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ํ˜ธ์ถœ bind()์ง€์ •๋œ ํฌํŠธ์—์„œ ํŒจํ‚ท์„ ์ˆ˜์‹ ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ์šด์˜ ์ฒด์ œ์— ์•Œ๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋Œ€์‹  ์„œ๋ฒ„ ํ‚ค ์•„๋ž˜์˜ Firebase์— ๊ฐœ๋ฐฉํ˜• ํฌํŠธ๋ฅผ ๊ฒŒ์‹œํ•˜๊ณ  ํ•ด๋‹น ํ•˜์œ„ ํŠธ๋ฆฌ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ํ˜ธ์ถœ recvfrom(), ์ด ํฌํŠธ์˜ ๋ชจ๋“  ํ˜ธ์ŠคํŠธ์—์„œ ๋“ค์–ด์˜ค๋Š” ํŒจํ‚ท์„ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์ด ํฌํŠธ๋กœ ์ „์†ก๋œ ํŒจํ‚ท์˜ ์ˆ˜์‹  ๋Œ€๊ธฐ์—ด์„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ ํฌํŠธ์—๋Š” ์ž์ฒด ๋Œ€๊ธฐ์—ด์ด ์žˆ์œผ๋ฉฐ, ์ƒˆ ํŒจํ‚ท์ด ๋„์ฐฉํ•  ๋•Œ ์–ด๋–ค ๋Œ€๊ธฐ์—ด๋กœ ์ „๋‹ฌํ• ์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก WebRTC ๋ฐ์ดํ„ฐ๊ทธ๋žจ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์†Œ์Šค ๋ฐ ๋Œ€์ƒ ํฌํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

ํ˜ธ์ถœ์€ ๋น„์ฐจ๋‹จ์ด๋ฏ€๋กœ ํŒจํ‚ท์ด ์—†์œผ๋ฉด ๊ฐ„๋‹จํžˆ -1์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. errno=EWOULDBLOCK.

  • ํด๋ผ์ด์–ธํŠธ๋Š” ์™ธ๋ถ€ ์ˆ˜๋‹จ์„ ํ†ตํ•ด ์„œ๋ฒ„์˜ IP์™€ ํฌํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. sendto(). ์ด๋Š” ๋‚ด๋ถ€ ํ˜ธ์ถœ๋„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. bind(), ๋”ฐ๋ผ์„œ ํ›„์† recvfrom() ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ”์ธ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์‘๋‹ต์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ๋Š” ์™ธ๋ถ€์—์„œ ๋ฌธ์ž์—ด ํ‚ค๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. resolve() IP ์ฃผ์†Œ๋ฅผ ์–ป์œผ๋ ค๋ฉด.

์ด ์‹œ์ ์—์„œ ๋‘ ํ”ผ์–ด๊ฐ€ ์•„์ง ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ WebRTC ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ”ผ์–ด์˜ ๋‹ค๋ฅธ ํฌํŠธ์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์€ ๋™์ผํ•œ WebRTC DataChannel์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„์ ‘์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. bind()๋‹ค์Œ์— ์„œ๋ฒ„๊ฐ€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋„๋ก sendto() ์–ด๋–ค ์ด์œ ๋กœ๋“  ๋ฌธ์„ ๋‹ซ์€ ๊ฒฝ์šฐ.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ Firebase์˜ ์„œ๋ฒ„ ํฌํŠธ ์ •๋ณด ์•„๋ž˜์— SDP ์ œ์•ˆ์„ ์ž‘์„ฑํ•  ๋•Œ ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ , ์„œ๋ฒ„๋Š” ๊ฑฐ๊ธฐ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์†Œ์ผ“ ๊ตฌ์„ฑํ‘œ์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€ ํ๋ฆ„์˜ ์˜ˆ์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ์˜ ์ฒซ ๋ฒˆ์งธ ๋ฉ”์‹œ์ง€ ์ „์†ก์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Cheerp, WebRTC ๋ฐ Firebase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C++์—์„œ ์›น์œผ๋กœ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ๊ฒŒ์ž„ ํฌํŒ…
ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์—ฐ๊ฒฐ ๋‹จ๊ณ„์— ๋Œ€ํ•œ ์ „์ฒด ๋‹ค์ด์–ด๊ทธ๋žจ

๊ฒฐ๋ก 

์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์—ˆ๋‹ค๋ฉด ์•„๋งˆ๋„ ์ด๋ก ์ด ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜๋Š” ๋ชจ์Šต์„ ๋ณด๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฒŒ์ž„์€ ๋‹ค์Œ์—์„œ ํ”Œ๋ ˆ์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. teeworlds.leaningtech.com, ์‹œ๋„ ํ•ด๋ด!


๋™๋ฃŒ๊ฐ„์˜ ์นœ์„ ๊ฒฝ๊ธฐ

๋„คํŠธ์›Œํฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์—์„œ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊นƒํ—ˆ๋ธŒ. ๋‹ค์Œ ์ฑ„๋„์—์„œ ๋Œ€ํ™”์— ์ฐธ์—ฌํ•˜์„ธ์š”. Gitter!

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€