ΠŸΡ€Π΅Π½Π°ΡΡΠ½Π΅ Π½Π° ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° ΠΎΡ‚ C++ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° с Cheerp, WebRTC ΠΈ Firebase

въвСдСниС

Π½Π°ΡˆΠ°Ρ‚Π° компания НаклонСни Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ прСдоставя Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π° прСнасянС Π½Π° Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΈ настолни прилоТСния към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°. ΠΠ°ΡˆΠΈΡΡ‚ C++ ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ вСсСли сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° комбинация ΠΎΡ‚ WebAssembly ΠΈ JavaScript, която прСдоставя ΠΈ лСсно взаимодСйствиС с Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°, ΠΈ висока производитСлност.

ΠšΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° прСнСсСм ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° Π·Π° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° ΠΈ ΠΈΠ·Π±Ρ€Π°Ρ…ΠΌΠ΅ Teeworlds. Teeworlds Π΅ Ρ€Π΅Ρ‚Ρ€ΠΎ XNUMXD ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° с ΠΌΠ°Π»ΠΊΠ°, Π½ΠΎ Π°ΠΊΡ‚ΠΈΠ²Π½Π° общност ΠΎΡ‚ ΠΈΠ³Ρ€Π°Ρ‡ΠΈ (Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΌΠ΅Π½!). Малък Π΅ ΠΊΠ°ΠΊΡ‚ΠΎ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ Π½Π° рСсурситС Π·Π° изтСглянС, Ρ‚Π°ΠΊΠ° ΠΈ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ Π½Π° изискванията Π·Π° CPU ΠΈ GPU – ΠΈΠ΄Π΅Π°Π»Π΅Π½ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚.

ΠŸΡ€Π΅Π½Π°ΡΡΠ½Π΅ Π½Π° ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° ΠΎΡ‚ C++ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° с Cheerp, WebRTC ΠΈ Firebase
Π Π°Π±ΠΎΡ‚ΠΈ Π² Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π° Teeworlds

Π Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π·Π° Π΄Π° СкспСримСнтирамС ΠΎΠ±Ρ‰ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π° прСнасянС Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ² ΠΊΠΎΠ΄ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°. Π’ΠΎΠ²Π° ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ сС ΠΏΡ€Π°Π²ΠΈ ΠΏΠΎ слСднитС Π½Π°Ρ‡ΠΈΠ½ΠΈ:

  • XMLHttpRequest/fetch, Π°ΠΊΠΎ ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° част сС ΡΡŠΡΡ‚ΠΎΠΈ само ΠΎΡ‚ HTTP заявки, ΠΈΠ»ΠΈ
  • WebSockets.

И Π΄Π²Π΅Ρ‚Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ изискват хостванС Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π΅Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΎΡ‚ страната Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° ΠΈ Π½ΠΈΡ‚ΠΎ Π΅Π΄Π½ΠΎ ΠΎΡ‚ тях Π½Π΅ позволява Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠ°Ρ‚ΠΎ транспортСн ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ». UDP. Π’ΠΎΠ²Π° Π΅ Π²Π°ΠΆΠ½ΠΎ Π·Π° прилоТСния Π² Ρ€Π΅Π°Π»Π½ΠΎ Π²Ρ€Π΅ΠΌΠ΅ ΠΊΠ°Ρ‚ΠΎ софтуСр Π·Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠΎΠ½Ρ„Π΅Ρ€Π΅Π½Ρ†ΠΈΠΈ ΠΈ ΠΈΠ³Ρ€ΠΈ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ доставката Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΈ ΠΏΠΎΡ€ΡŠΡ‡ΠΊΠ°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π° TCP ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠΏΡ€Π΅Ρ‡ΠΈ Π½Π° ниската латСнтност.

Има ΠΈ Ρ‚Ρ€Π΅Ρ‚ΠΈ Π½Π°Ρ‡ΠΈΠ½ - Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° ΠΎΡ‚ Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°: WebRTC.

RTCDataChannel ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΊΠ°ΠΊΡ‚ΠΎ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΎ, Ρ‚Π°ΠΊΠ° ΠΈ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΎ ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ (Π² послСдния случай сС ΠΎΠΏΠΈΡ‚Π²Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° UDP ΠΊΠ°Ρ‚ΠΎ транспортСн ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΅ възмоТно) ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠ°ΠΊΡ‚ΠΎ с ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€, Ρ‚Π°ΠΊΠ° ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Π±Ρ€Π°ΡƒΠ·ΡŠΡ€ΠΈ. Π’ΠΎΠ²Π° ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° прСнСсСм цялото ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ към Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΡΡŠΡ€Π²ΡŠΡ€Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚!

Π’ΠΎΠ²Π° ΠΎΠ±Π°Ρ‡Π΅ ΠΈΠ΄Π²Π° с Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° трудност: ΠΏΡ€Π΅Π΄ΠΈ Π΄Π²Π° WebRTC ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€Π° Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° ΠΊΠΎΠΌΡƒΠ½ΠΈΠΊΠΈΡ€Π°Ρ‚, Ρ‚Π΅ трябва Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠ°Ρ‚ сравнитСлно слоТно Ρ€ΡŠΠΊΠΎΡΡ‚ΠΈΡΠΊΠ°Π½Π΅, Π·Π° Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ°Ρ‚, ΠΊΠΎΠ΅Ρ‚ΠΎ изисква мноТСство ΠΎΠ±Π΅ΠΊΡ‚ΠΈ Π½Π° Ρ‚Ρ€Π΅Ρ‚ΠΈ страни (ΡΡŠΡ€Π²ΡŠΡ€ Π·Π° сигнализиранС ΠΈ Π΅Π΄ΠΈΠ½ ΠΈΠ»ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π—ΠΠ¨Π•ΠœΠ•Π’Π―Π’ΠΠΠ•/Π’ΠͺΠ Π’Π•Π’Π•).

Π’ идСалния случай Π±ΠΈΡ…ΠΌΠ΅ искали Π΄Π° създадСм ΠΌΡ€Π΅ΠΆΠΎΠ² API, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΎ WebRTC, Π½ΠΎ Π΅ възмоТно Π½Π°ΠΉ-Π±Π»ΠΈΠ·ΠΎ Π΄ΠΎ интСрфСйса Π½Π° UDP Sockets, ΠΊΠΎΠΉΡ‚ΠΎ Π½Π΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ ΠΎΡ‚ установяванС Π½Π° Π²Ρ€ΡŠΠ·ΠΊΠ°.

Π’ΠΎΠ²Π° Ρ‰Π΅ Π½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π΄Π° сС възползвамС ΠΎΡ‚ WebRTC, Π±Π΅Π· Π΄Π° сС Π½Π°Π»Π°Π³Π° Π΄Π° ΠΈΠ·Π»Π°Π³Π°ΠΌΠ΅ слоТни Π΄Π΅Ρ‚Π°ΠΉΠ»ΠΈ Π½Π° ΠΊΠΎΠ΄Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ (ΠΊΠΎΠΉΡ‚ΠΎ искахмС Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΠΌ възмоТно Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΎ Π² нашия ΠΏΡ€ΠΎΠ΅ΠΊΡ‚).

ΠœΠΈΠ½ΠΈΠΌΡƒΠΌ WebRTC

WebRTC Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ API, Π½Π°Π»ΠΈΡ‡Π½ΠΈ Π² Π±Ρ€Π°ΡƒΠ·ΡŠΡ€ΠΈΡ‚Π΅ Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π°ΡƒΠ΄ΠΈΠΎ, Π²ΠΈΠ΄Π΅ΠΎ ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ Ρ‚ΠΈΠΏ peer-to-peer.

Π’Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈΡ‚Π΅ сС установява (Π΄ΠΎΡ€ΠΈ Π°ΠΊΠΎ ΠΈΠΌΠ° NAT ΠΎΡ‚ Π΅Π΄Π½Π°Ρ‚Π° ΠΈΠ»ΠΈ Π΄Π²Π΅Ρ‚Π΅ страни) с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° STUN ΠΈ/ΠΈΠ»ΠΈ TURN ΡΡŠΡ€Π²ΡŠΡ€ΠΈ Ρ‡Ρ€Π΅Π· ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ, Π½Π°Ρ€Π΅Ρ‡Π΅Π½ ICE. ΠŸΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈΡ‚Π΅ обмСнят ICE информация ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ Π½Π° ΠΊΠ°Π½Π°Π»Π° Ρ‡Ρ€Π΅Π· ΠΎΡ„Π΅Ρ€Ρ‚Π°Ρ‚Π° ΠΈ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π° Π½Π° SDP ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.

Π•Ρ…Π°! Колко ΡΡŠΠΊΡ€Π°Ρ‰Π΅Π½ΠΈΡ навСднъТ. НСка Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ обясним ΠΊΠ°ΠΊΠ²ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°Ρ‚ Ρ‚Π΅Π·ΠΈ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈ:

  • ΠŸΠΎΠΌΠΎΡ‰Π½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅ Π½Π° сСсия Π·Π° NAT (Π—ΠΠ¨Π•ΠœΠ•Π’Π―Π’ΠΠΠ•) - ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π·Π° заобикалянС Π½Π° NAT ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° Π΄Π²ΠΎΠΉΠΊΠ° (IP, ΠΏΠΎΡ€Ρ‚) Π·Π° Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½Π° комуникация с хоста. Ако Ρ‚ΠΎΠΉ успСС Π΄Π° изпълни Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° си, Ρ‚ΠΎΠ³Π°Π²Π° ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈΡ‚Π΅ ΠΌΠΎΠ³Π°Ρ‚ нСзависимо Π΄Π° обмСнят Π΄Π°Π½Π½ΠΈ ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си.
  • ΠŸΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅ с ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ€Π΅Π»Π΅Ρ‚Π° ΠΎΠΊΠΎΠ»ΠΎ NAT (Π’ΠͺΠ Π’Π•Π’Π•) ΡΡŠΡ‰ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° заобикалянС Π½Π° NAT, Π½ΠΎ ΠΏΡ€Π°Π²ΠΈ Ρ‚ΠΎΠ²Π° Ρ‡Ρ€Π΅Π· ΠΏΡ€Π΅ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΏΡ€Π΅Π· прокси, Π²ΠΈΠ΄ΠΈΠΌΠΎ ΠΈ Π·Π° Π΄Π²Π°ΠΌΠ°Ρ‚Π° ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ. Π’ΠΎΠΉ добавя латСнтност ΠΈ Π΅ ΠΏΠΎ-скъп Π·Π° изпълнСниС ΠΎΡ‚ STUN (Π·Π°Ρ‰ΠΎΡ‚ΠΎ сС ΠΏΡ€ΠΈΠ»Π°Π³Π° ΠΏΡ€Π΅Π· цялата сСсия), Π½ΠΎ понякога Π΅ СдинствСната опция.
  • УстановяванС Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π° ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎΡΡ‚ (ICE) сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΈΠ·Π±ΠΎΡ€ Π½Π° Π½Π°ΠΉ-добрия възмоТСн Π½Π°Ρ‡ΠΈΠ½ Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ Π½Π° Π΄Π²Π°ΠΌΠ° ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ въз основа Π½Π° информацията, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π° ΠΎΡ‚ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ Π½Π° ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ информация, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π° ΠΎΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ Π±Ρ€ΠΎΠΉ STUN ΠΈ TURN ΡΡŠΡ€Π²ΡŠΡ€ΠΈ.
  • ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π·Π° описаниС Π½Π° сСсията (SDP) - Ρ‚ΠΎΠ²Π° Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π·Π° описаниС Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΊΠ°Π½Π°Π»Π° Π·Π° Π²Ρ€ΡŠΠ·ΠΊΠ°, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΈ Π·Π° ICE, ΠΌΡƒΠ»Ρ‚ΠΈΠΌΠ΅Π΄ΠΈΠΉΠ½ΠΈ ΠΊΠΎΠ΄Π΅Ρ†ΠΈ (Π² случай Π½Π° Π°ΡƒΠ΄ΠΈΠΎ / Π²ΠΈΠ΄Π΅ΠΎ ΠΊΠ°Π½Π°Π») ΠΈ Ρ‚.Π½. Единият ΠΎΡ‚ ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈΡ‚Π΅ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π° SDP ΠΎΡ„Π΅Ρ€Ρ‚Π° (β€žΠΎΡ„Π΅Ρ€Ρ‚Π°β€œ), Π° вторият отговаря с SDP ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ (β€žΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€β€œ). Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° сС създава ΠΊΠ°Π½Π°Π».

Π—Π° Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π°Ρ‚ Ρ‚Π°ΠΊΠ°Π²Π° Π²Ρ€ΡŠΠ·ΠΊΠ°, ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈΡ‚Π΅ трябва Π΄Π° ΡΡŠΠ±ΠΈΡ€Π°Ρ‚ информацията, която ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚ ΠΎΡ‚ ΡΡŠΡ€Π²ΡŠΡ€ΠΈΡ‚Π΅ STUN ΠΈ TURN, ΠΈ Π΄Π° я обмСнят ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡŠΡ‚ Π΅, Ρ‡Π΅ Ρ‚Π΅ всС ΠΎΡ‰Π΅ нямат Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° обмСнят Π΄Π°Π½Π½ΠΈ Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ трябва Π΄Π° ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ извън Π»Π΅Π½Ρ‚Π°Ρ‚Π° Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ: сигнализиращ ΡΡŠΡ€Π²ΡŠΡ€.

Π‘ΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ Π·Π° сигнализиранС ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΌΠ½ΠΎΠ³ΠΎ прост, Π·Π°Ρ‰ΠΎΡ‚ΠΎ СдинствСната ΠΌΡƒ Π·Π°Π΄Π°Ρ‡Π° Π΅ Π΄Π° ΠΏΡ€Π΅ΠΏΡ€Π°Ρ‰Π° Π΄Π°Π½Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π΅Ρ‚Π°ΠΏΠ° Π½Π° "Ρ€ΡŠΠΊΠΎΡΡ‚ΠΈΡΠΊΠ°Π½Π΅" (ΠΊΠ°ΠΊΡ‚ΠΎ Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ).

ΠŸΡ€Π΅Π½Π°ΡΡΠ½Π΅ Π½Π° ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° ΠΎΡ‚ C++ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° с Cheerp, WebRTC ΠΈ Firebase
ΠžΠΏΡ€ΠΎΡΡ‚Π΅Π½Π° послСдоватСлност Π½Π° Ρ€ΡŠΠΊΠΎΡΡ‚ΠΈΡΠΊΠ°Π½Π΅ Π½Π° WebRTC

ΠŸΡ€Π΅Π³Π»Π΅Π΄ Π½Π° мрСТовия ΠΌΠΎΠ΄Π΅Π» Π½Π° Teeworlds

ΠœΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π½Π° Teeworlds Π΅ ΠΌΠ½ΠΎΠ³ΠΎ проста:

  • ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΡ‚Π΅ ΠΈ ΡΡŠΡ€Π²ΡŠΡ€Π½ΠΈΡ‚Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ са Π΄Π²Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ.
  • ΠšΠ»ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π²Π»ΠΈΠ·Π°Ρ‚ Π² ΠΈΠ³Ρ€Π°Ρ‚Π°, ΠΊΠ°Ρ‚ΠΎ сС ΡΠ²ΡŠΡ€Π·Π²Π°Ρ‚ към Π΅Π΄ΠΈΠ½ ΠΎΡ‚ няколко ΡΡŠΡ€Π²ΡŠΡ€Π°, ΠΊΠ°Ρ‚ΠΎ всСки хоства само Π΅Π΄Π½Π° ΠΈΠ³Ρ€Π° навСднъТ.
  • Цялото ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ Π² ΠΈΠ³Ρ€Π°Ρ‚Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° ΠΏΡ€Π΅Π· ΡΡŠΡ€Π²ΡŠΡ€Π°.
  • Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»Π΅Π½ Π³Π»Π°Π²Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΡΡŠΠ±ΠΈΡ€Π°Π½Π΅ Π½Π° списък Π½Π° всички ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ сС ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ‚ Π² ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°.

Π‘Π»Π°Π³ΠΎΠ΄Π°Ρ€Π΅Π½ΠΈΠ΅ Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° WebRTC Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Π΄Π°Π½Π½ΠΈ, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΠΈΠΌ ΡΡŠΡ€Π²ΡŠΡ€Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π° към Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ сС Π½Π°ΠΌΠΈΡ€Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡŠΡ‚. Π’ΠΎΠ²Π° Π½ΠΈ Π΄Π°Π²Π° чудСсна Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚...

ΠžΡ‚ΡŠΡ€Π²Π΅Ρ‚Π΅ сС ΠΎΡ‚ ΡΡŠΡ€Π²ΡŠΡ€ΠΈΡ‚Π΅

Липсата Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ° ΠΎΡ‚ страна Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° ΠΈΠΌΠ° Ρ…ΡƒΠ±Π°Π²ΠΎ прСдимство: ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ цялото ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠ°Ρ‚ΠΎ статично ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅ Π½Π° Github страници ΠΈΠ»ΠΈ Π½Π° нашия собствСн Ρ…Π°Ρ€Π΄ΡƒΠ΅Ρ€ Π·Π°Π΄ Cloudflare, ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°ΠΌΠ΅ Π±ΡŠΡ€Π·ΠΈ изтСгляния ΠΈ дълго Π²Ρ€Π΅ΠΌΠ΅ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° Π±Π΅Π·ΠΏΠ»Π°Ρ‚Π½ΠΎ. Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‰Π΅ бъдС възмоТно Π΄Π° Π·Π°Π±Ρ€Π°Π²ΠΈΠΌ Π·Π° тях ΠΈ Π°ΠΊΠΎ ΠΈΠΌΠ°ΠΌΠ΅ ΠΊΡŠΡΠΌΠ΅Ρ‚ ΠΈ ΠΈΠ³Ρ€Π°Ρ‚Π° станС популярна, Ρ‚ΠΎΠ³Π°Π²Π° инфраструктурата няма Π΄Π° сС Π½Π°Π»Π°Π³Π° Π΄Π° сС Π½Π°Π΄Π³Ρ€Π°ΠΆΠ΄Π°.

Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, Π·Π° Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ систСмата, всС ΠΎΡ‰Π΅ трябва Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ външна Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°:

  • Π•Π΄ΠΈΠ½ ΠΈΠ»ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅ STUN ΡΡŠΡ€Π²ΡŠΡ€ΠΈ: ИмамС няколко Π±Π΅Π·ΠΏΠ»Π°Ρ‚Π½ΠΈ ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΈΠ·Π±ΠΎΡ€.
  • ПонС Π΅Π΄ΠΈΠ½ TURN ΡΡŠΡ€Π²ΡŠΡ€: Ρ‚ΡƒΠΊ няма Π±Π΅Π·ΠΏΠ»Π°Ρ‚Π½ΠΈ ΠΎΠΏΡ†ΠΈΠΈ, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ»ΠΈ Π΄Π° настроим наш собствСн, ΠΈΠ»ΠΈ Π΄Π° ΠΏΠ»Π°Ρ‚ΠΈΠΌ Π·Π° услугата. Π—Π° щастиС ΠΏΡ€Π΅Π· ΠΏΠΎΠ²Π΅Ρ‡Π΅Ρ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Ρ‰Π΅ бъдС възмоТно Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ΅Ρ‚Π΅ Ρ‡Ρ€Π΅Π· STUN ΡΡŠΡ€Π²ΡŠΡ€ΠΈ (ΠΈ Π΄Π° осигуритС истински p2p), Π½ΠΎ TURN Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊΠ°Ρ‚ΠΎ Ρ€Π΅Π·Π΅Ρ€Π²Π΅Π½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.
  • Π‘ΡŠΡ€Π²ΡŠΡ€ Π·Π° сигнализиранС: Π—Π° Ρ€Π°Π·Π»ΠΈΠΊΠ° ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ Π΄Π²Π° аспСкта, сигнализиранСто Π½Π΅ Π΅ стандартизирано. Π—Π° ΠΊΠ°ΠΊΠ²ΠΎ Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‰Π΅ отговаря ΡΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ Π·Π° сигнализиранС зависи донякъдС ΠΎΡ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ. Π’ нашия случай, ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° сС установи Π²Ρ€ΡŠΠ·ΠΊΠ°, Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС ΠΎΠ±ΠΌΠ΅Π½ΠΈ ΠΌΠ°Π»ΠΊΠΎ количСство Π΄Π°Π½Π½ΠΈ.
  • Π“Π»Π°Π²Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€ Π½Π° Teeworlds: ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° сС ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ Π·Π° обявяванС Π½Π° ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ ΠΈ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈ Π·Π° Π½Π°ΠΌΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΠΈ. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‡Π΅ Π½Π΅ Π΅ Π·Π°Π΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎ (ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π²ΠΈΠ½Π°Π³ΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ°Ρ‚ Ρ€ΡŠΡ‡Π½ΠΎ със ΡΡŠΡ€Π²ΡŠΡ€, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΠΎΠ·Π½Π°Π²Π°Ρ‚), Π±ΠΈ Π±ΠΈΠ»ΠΎ Ρ…ΡƒΠ±Π°Π²ΠΎ Π΄Π° Π³ΠΎ ΠΈΠΌΠ°, Π·Π° Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ ΠΈΠ³Ρ€Π°Ρ‡ΠΈΡ‚Π΅ Π΄Π° играят ΠΈΠ³Ρ€ΠΈ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ Ρ…ΠΎΡ€Π°.

Π Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π±Π΅Π·ΠΏΠ»Π°Ρ‚Π½ΠΈΡ‚Π΅ STUN ΡΡŠΡ€Π²ΡŠΡ€ΠΈ Π½Π° Google ΠΈ сами Π²Π½Π΅Π΄Ρ€ΠΈΡ…ΠΌΠ΅ Π΅Π΄ΠΈΠ½ TURN ΡΡŠΡ€Π²ΡŠΡ€.

Π—Π° послСднитС Π΄Π²Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…ΠΌΠ΅ Firebase:

  • Главният ΡΡŠΡ€Π²ΡŠΡ€ Π½Π° Teeworlds Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½ ΠΌΠ½ΠΎΠ³ΠΎ просто: ΠΊΠ°Ρ‚ΠΎ списък ΠΎΡ‚ ΠΎΠ±Π΅ΠΊΡ‚ΠΈ, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ информация (ΠΈΠΌΠ΅, IP, ΠΊΠ°Ρ€Ρ‚Π°, Ρ€Π΅ΠΆΠΈΠΌ, ...) Π½Π° всСки Π°ΠΊΡ‚ΠΈΠ²Π΅Π½ ΡΡŠΡ€Π²ΡŠΡ€. Π‘ΡŠΡ€Π²ΡŠΡ€ΠΈΡ‚Π΅ ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°Ρ‚ ΠΈ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚ своитС собствСни ΠΎΠ±Π΅ΠΊΡ‚ΠΈ, Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π²Π·Π΅ΠΌΠ°Ρ‚ цСлия списък ΠΈ Π³ΠΎ ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ‚ Π½Π° ΠΈΠ³Ρ€Π°Ρ‡Π°. НиС ΡΡŠΡ‰ΠΎ ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌΠ΅ списъка ΠΊΠ°Ρ‚ΠΎ HTML Π½Π° Π½Π°Ρ‡Π°Π»Π½Π°Ρ‚Π° страница, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΈΠ³Ρ€Π°Ρ‡ΠΈΡ‚Π΅ Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ просто Π΄Π° ΠΊΠ»ΠΈΠΊΠ½Π°Ρ‚ Π²ΡŠΡ€Ρ…Ρƒ ΡΡŠΡ€Π²ΡŠΡ€Π° ΠΈ Π΄Π° влязат Π½Π°ΠΏΡ€Π°Π²ΠΎ Π² ΠΈΠ³Ρ€Π°Ρ‚Π°.
  • Π‘ΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π΅ тясно ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ с Π½Π°ΡˆΠ°Ρ‚Π° рСализация Π½Π° сокСт, описана Π² слСдващия Ρ€Π°Π·Π΄Π΅Π».

ΠŸΡ€Π΅Π½Π°ΡΡΠ½Π΅ Π½Π° ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° ΠΎΡ‚ C++ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° с Cheerp, WebRTC ΠΈ Firebase
Бписък със ΡΡŠΡ€Π²ΡŠΡ€ΠΈ Π² ΠΈΠ³Ρ€Π°Ρ‚Π° ΠΈ Π½Π° Π½Π°Ρ‡Π°Π»Π½Π°Ρ‚Π° страница

ВнСдряванС Π½Π° сокСт

ИскамС Π΄Π° създадСм API, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ възмоТно Π½Π°ΠΉ-Π±Π»ΠΈΠ·ΠΎ Π΄ΠΎ Posix UDP Sockets, Π·Π° Π΄Π° свСдСм Π΄ΠΎ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ броя Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ.

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° искамС Π΄Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌ нСобходимия ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ Π·Π° Π½Π°ΠΉ-простия ΠΎΠ±ΠΌΠ΅Π½ Π½Π° Π΄Π°Π½Π½ΠΈ Π² ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°.

НапримСр, Π½Π΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ‚ истинско ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·ΠΈΡ€Π°Π½Π΅: всички ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ са Π² Π΅Π΄Π½Π° ΠΈ ΡΡŠΡ‰Π° β€žΠ²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° LANβ€œ, ΡΠ²ΡŠΡ€Π·Π°Π½Π° с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ СкзСмпляр Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ Π½Π° Firebase.

Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ Π½Π΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ‚ ΡƒΠ½ΠΈΠΊΠ°Π»Π½ΠΈ 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 Π΅ прост ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π½Π° API Π½Π° Posix Sockets, Π½ΠΎ с няколко Π²Π°ΠΆΠ½ΠΈ Ρ€Π°Π·Π»ΠΈΠΊΠΈ: рСгистриранС Π½Π° ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅, Π»ΠΎΠΊΠ°Π»Π½ΠΎ 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 присвояванС

Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π½Π° Π²ΡŠΠ·Π»ΠΈΡ‚Π΅ Π² Π½Π°ΡˆΠ°Ρ‚Π° β€žΠΌΡ€Π΅ΠΆΠ°β€œ Π½Π΅ са 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() Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π° Π±Π΅Π· ΠΈΠ·Ρ€ΠΈΡ‡Π½ΠΎ изпълнСниС Π½Π° bind.

Π’ нашия случай ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡŠΡ‚ външно ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π° ΠΊΠ»ΡŽΡ‡ ΠΎΡ‚ Π½ΠΈΠ· ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° функцията resolve() Π·Π° Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ IP адрСс.

Π’ Ρ‚ΠΎΠ·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΌΠ΅ WebRTC Ρ€ΡŠΠΊΠΎΡΡ‚ΠΈΡΠΊΠ°Π½Π΅Ρ‚ΠΎ, Π°ΠΊΠΎ Π΄Π²Π°ΠΌΠ°Ρ‚Π° ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ΠΈ всС ΠΎΡ‰Π΅ Π½Π΅ са ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ Π΅Π΄ΠΈΠ½ с Π΄Ρ€ΡƒΠ³. Π’Ρ€ΡŠΠ·ΠΊΠΈΡ‚Π΅ към Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΠΎΡ€Ρ‚ΠΎΠ²Π΅ Π½Π° Π΅Π΄ΠΈΠ½ ΠΈ ΡΡŠΡ‰ΠΈ ΠΏΠ°Ρ€Ρ‚Π½ΡŒΠΎΡ€ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π΅Π΄ΠΈΠ½ ΠΈ ΡΡŠΡ‰ WebRTC DataChannel.

ΠŸΡ€Π°Π²ΠΈΠΌ ΠΈ ΠΈΠ½Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΈ bind()Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΡΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΡΠ²ΡŠΡ€ΠΆΠ΅ ΠΎΡ‚Π½ΠΎΠ²ΠΎ слСд Ρ‚ΠΎΠ²Π° sendto() Π² случай Ρ‡Π΅ сС Π·Π°Ρ‚Π²ΠΎΡ€ΠΈ ΠΏΠΎ някаква ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°.

Π‘ΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ сС увСдомява Π·Π° Π²Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡŠΡ‚ напишС своята SDP ΠΎΡ„Π΅Ρ€Ρ‚Π° ΠΏΠΎΠ΄ информацията Π·Π° ΠΏΠΎΡ€Ρ‚Π° Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° във Firebase ΠΈ ΡΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ отговаря с ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π° си ΠΈ Ρ‚Π°ΠΌ.

Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ ΠΏΠΎΠΊΠ°Π·Π²Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΏΠΎΡ‚ΠΎΠΊ ΠΎΡ‚ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ Π·Π° схСмата Π½Π° сокСта ΠΈ ΠΏΡŠΡ€Π²ΠΎΡ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° към ΡΡŠΡ€Π²ΡŠΡ€Π°:

ΠŸΡ€Π΅Π½Π°ΡΡΠ½Π΅ Π½Π° ΠΌΡƒΠ»Ρ‚ΠΈΠΏΠ»Π΅ΠΉΡŠΡ€ ΠΈΠ³Ρ€Π° ΠΎΡ‚ C++ към ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° с Cheerp, WebRTC ΠΈ Firebase
Пълна Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠ° Π½Π° Ρ„Π°Π·Π°Ρ‚Π° Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ ΡΡŠΡ€Π²ΡŠΡ€

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Ако стС ΠΏΡ€ΠΎΡ‡Π΅Π»ΠΈ Π΄ΠΎ Ρ‚ΡƒΠΊ, ΠΌΠΎΠΆΠ΅ Π΄Π° Π²ΠΈ Π΅ интСрСсно Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ тСорията Π² дСйствиС. Π˜Π³Ρ€Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ³Ρ€Π°Π΅ Π½Π° teeworlds.leaningtech.com, ΠΎΠΏΠΈΡ‚Π°ΠΉ!


ΠŸΡ€ΠΈΡΡ‚Π΅Π»ΡΠΊΠΈ ΠΌΠ°Ρ‡ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠ»Π΅Π³ΠΈ

ΠšΠΎΠ΄ΡŠΡ‚ Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π΅ свободно Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½ Π½Π° Github. ΠŸΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½Π΅Ρ‚Π΅ сС към Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° Π² нашия ΠΊΠ°Π½Π°Π» Ρ€Π΅ΡˆΠ΅Ρ‚ΠΊΠ°!

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€