Porting ntau qhov kev ua si los ntawm C ++ mus rau lub vev xaib nrog Cheerp, WebRTC thiab Firebase

Taw qhia

peb lub tuam txhab Leaning Technologies muab cov kev daws teeb meem rau porting ib txwm desktop daim ntawv thov mus rau lub vev xaib. Peb C++ compiler zoo siab tsim kev sib txuas ntawm WebAssembly thiab JavaScript, uas muab ob qho tib si yooj yim browser sib cuam tshuam, thiab kev ua haujlwm siab.

Raws li ib qho piv txwv ntawm nws daim ntawv thov, peb txiav txim siab los port ib tug multiplayer game rau lub web thiab xaiv Tsov Tom Neeg. Teeworlds yog multiplayer 2D retro game nrog lub zej zog me tab sis nquag ntawm cov neeg ua si (xws li kuv!). Nws yog me me nyob rau hauv cov nqe lus ntawm rub tawm cov peev txheej thiab CPU thiab GPU yuav tsum - tus neeg sib tw zoo tshaj.

Porting ntau qhov kev ua si los ntawm C ++ mus rau lub vev xaib nrog Cheerp, WebRTC thiab Firebase
Khiav hauv Teeworlds browser

Peb txiav txim siab los siv qhov project no los sim nrog cov kev daws teeb meem dav dav rau porting network code rau lub vev xaib. Qhov no feem ntau yog ua raws li hauv qab no:

  • XMLHttpRequest/fetch, yog hais tias lub network ib feem tsuas muaj HTTP thov, los yog
  • lub vev xaib.

Ob qho kev daws teeb meem xav tau hosting cov khoom siv server ntawm sab server, thiab tsis tso cai rau siv raws li kev thauj mus los UDP. Qhov no yog qhov tseem ceeb rau cov ntawv thov hauv lub sijhawm xws li video conferencing software thiab games, vim tias nws lav qhov kev xa khoom thiab kev txiav txim ntawm pob ntawv raws tu qauv TCP tuaj yeem dhau los ua qhov cuam tshuam rau qis latency.

Muaj ib txoj kev thib peb - ​​siv lub network los ntawm browser: WebRTC.

RTCDataChannel Nws txhawb nqa kev sib kis tau zoo thiab tsis ntseeg siab (hauv qhov kawg nws sim siv UDP raws li kev thauj mus los thaum twg los tau), thiab tuaj yeem siv tau ob qho tib si nrog cov chaw taws teeb tswj thiab nruab nrab ntawm cov browsers. Qhov no txhais tau tias peb tuaj yeem xa tag nrho daim ntawv thov mus rau qhov browser, suav nrog cov khoom siv server!

Txawm li cas los xij, qhov no los nrog qhov nyuaj ntxiv: ua ntej ob tus neeg sib tw WebRTC tuaj yeem sib txuas lus, lawv yuav tsum tau ua ib qho kev sib koom tes sib txuas, uas yuav tsum muaj ntau lub koom haum thib peb (ib lub cim qhia thiab ib lossis ntau lub servers. STUN/TURN).

Qhov zoo tshaj plaws, peb xav tsim lub network API uas siv WebRTC sab hauv, tab sis yog ze li sai tau rau UDP Sockets interface uas tsis tas yuav tsim kev sib txuas.

Qhov no yuav tso cai rau peb coj kom zoo dua WebRTC yam tsis tas yuav nthuav tawm cov ntsiab lus nyuaj rau daim ntawv thov code (uas peb xav hloov tsawg li tsawg tau hauv peb qhov project).

Yam tsawg kawg WebRTC

WebRTC yog ib txheej APIs muaj nyob rau hauv browsers uas muab cov phooj ywg-rau-peer kis tau tus mob ntawm cov suab, video thiab arbitrary ntaub ntawv.

Kev sib txuas ntawm cov phooj ywg yog tsim los (txawm tias muaj NAT ntawm ib lossis ob sab) siv STUN thiab / lossis TURN servers los ntawm lub tshuab hu ua ICE. Cov phooj ywg sib pauv ICE cov ntaub ntawv thiab cov kev txwv tsis pub dhau los ntawm kev muab thiab lus teb ntawm SDP raws tu qauv.

Wow! Muaj pes tsawg daim ntawv luv luv ntawm ib zaug? Cia peb piav me ntsis txog cov ntsiab lus no txhais li cas:

  • Session Traversal Utilities rau NAT (STUN) - cov txheej txheem rau kev hla NAT thiab tau txais ib khub (IP, chaw nres nkoj) rau kev sib pauv cov ntaub ntawv ncaj qha nrog tus tswv tsev. Yog tias nws tswj kom ua tiav nws txoj haujlwm, cov phooj ywg tuaj yeem sib pauv cov ntaub ntawv ntawm ib leeg.
  • Kev siv Relays ncig NAT (TURN) kuj tseem siv rau NAT traversal, tab sis nws siv qhov no los ntawm kev xa cov ntaub ntawv los ntawm tus neeg sawv cev uas pom tau rau ob leeg phooj ywg. Nws ntxiv latency thiab kim dua los siv dua STUN (vim nws tau siv thoob plaws hauv kev sib tham tag nrho), tab sis qee zaum nws yog qhov kev xaiv nkaus xwb.
  • Kev Sib Tham Sib Txuas Kev Tsim Kho (ICE) siv los xaiv txoj kev zoo tshaj plaws ntawm kev sib txuas ntawm ob tus phooj ywg raws li cov ntaub ntawv tau los ntawm kev sib txuas cov phooj ywg ncaj qha, nrog rau cov ntaub ntawv tau txais los ntawm ib tus naj npawb ntawm STUN thiab TURN servers.
  • Session Description Protocol (RDS) yog ib hom kev piav qhia txog kev sib txuas channel tsis, piv txwv li, ICE cov neeg sib tw, multimedia codecs (nyob rau hauv rooj plaub ntawm lub suab / video channel), thiab lwm yam. .. Tom qab no, ib tug channel yog tsim.

Txhawm rau tsim kev sib txuas zoo li no, cov phooj ywg yuav tsum tau sau cov ntaub ntawv uas lawv tau txais los ntawm STUN thiab TURN servers thiab sib pauv nrog ib leeg.

Qhov teeb meem yog tias lawv tseem tsis tau muaj peev xwm sib txuas lus ncaj qha, yog li ib qho kev tawm ntawm pawg yuav tsum muaj los pauv cov ntaub ntawv no: lub teeb liab server.

Lub teeb liab neeg rau zaub mov tuaj yeem yooj yim heev vim tias nws txoj haujlwm tsuas yog xa cov ntaub ntawv ntawm cov phooj ywg nyob rau theem kev sib tuav tes (raws li qhia hauv daim duab hauv qab no).

Porting ntau qhov kev ua si los ntawm C ++ mus rau lub vev xaib nrog Cheerp, WebRTC thiab Firebase
Simplified WebRTC handshake sequence diagram

Teeworlds Network Model Txheej txheem cej luam

Teeworlds network architecture yog qhov yooj yim heev:

  • Cov neeg siv khoom thiab cov khoom siv server yog ob qhov sib txawv.
  • Cov neeg siv khoom nkag mus rau qhov kev ua si los ntawm kev txuas mus rau ib qho ntawm ntau lub servers, txhua tus uas tuav ib qho kev ua si ntawm ib lub sijhawm.
  • Tag nrho cov ntaub ntawv hloov mus rau hauv qhov kev ua si yog nqa tawm los ntawm lub server.
  • Tus neeg rau zaub mov tshwj xeeb yog siv los sau cov npe ntawm txhua tus pej xeem servers uas tau tshwm sim hauv cov neeg siv khoom ua si.

Ua tsaug rau kev siv WebRTC rau kev sib pauv cov ntaub ntawv, peb tuaj yeem hloov pauv cov server tivthaiv ntawm qhov kev ua si mus rau qhov browser uas tus neeg siv khoom nyob. Qhov no muab lub sijhawm zoo rau peb ...

Tshem tawm cov servers

Qhov tsis muaj neeg rau zaub mov logic muaj qhov zoo dua: peb tuaj yeem xa tag nrho daim ntawv thov raws li cov ntsiab lus zoo li qub ntawm Github Nplooj ntawv lossis ntawm peb tus kheej kho vajtse tom qab Cloudflare, yog li ua kom muaj kev rub tawm sai thiab ua haujlwm siab dawb. Qhov tseeb, peb tuaj yeem hnov ​​​​qab txog lawv, thiab yog tias peb muaj hmoo thiab qhov kev ua si tau nrov, ces cov kev tsim kho vaj tse yuav tsis tau ua kom zoo dua qub.

Txawm li cas los xij, rau qhov system ua haujlwm, peb tseem yuav tsum tau siv cov khoom siv sab nraud:

  • Ib lossis ntau dua STUN servers: Peb muaj ntau yam kev xaiv dawb xaiv los ntawm.
  • Tsawg kawg yog ib qho TURN server: tsis muaj kev xaiv pub dawb ntawm no, yog li peb tuaj yeem teeb tsa peb tus kheej lossis them rau qhov kev pabcuam. Hmoov zoo, feem ntau ntawm lub sijhawm kev sib txuas tuaj yeem tsim los ntawm STUN servers (thiab muab qhov tseeb p2p), tab sis TURN yog qhov xav tau los ua qhov kev xaiv rov qab.
  • Signaling Server: Tsis zoo li ob qho tib si, kev taw qhia tsis yog tus qauv. Dab tsi lub signaling server yuav ua tau lub luag haujlwm yog nyob ntawm qee yam ntawm daim ntawv thov. Hauv peb cov ntaub ntawv, ua ntej tsim kev sib txuas, nws yog ib qho tsim nyog los pauv cov ntaub ntawv me me.
  • Teeworlds Master Server: Nws yog siv los ntawm lwm cov servers los tshaj tawm lawv lub neej thiab los ntawm cov neeg siv khoom los nrhiav pej xeem servers. Txawm hais tias nws tsis tas yuav tsum tau (cov neeg siv khoom tuaj yeem txuas mus rau ib tus neeg rau zaub mov lawv paub txog manually), nws yuav zoo kom muaj kom cov neeg ua si tuaj yeem koom nrog kev ua si nrog cov neeg random.

Peb tau txiav txim siab siv Google STUN servers dawb, thiab siv ib qho TURN server peb tus kheej.

Rau ob lub ntsiab lus kawg peb siv Firebase:

  • Teeworlds master server yog siv yooj yim heev: raws li cov npe ntawm cov khoom muaj cov ntaub ntawv (npe, IP, daim ntawv qhia, hom, ...) ntawm txhua tus neeg rau zaub mov nquag. Servers tshaj tawm thiab hloov kho lawv tus kheej cov khoom, thiab cov neeg siv khoom nqa tag nrho cov npe thiab tso tawm rau tus neeg ua si. Peb kuj tso saib cov npe ntawm nplooj ntawv home li HTML yog li cov players tuaj yeem nyem rau ntawm server thiab coj ncaj qha mus rau qhov kev ua si.
  • Kev taw qhia yog ze ze rau peb qhov kev siv lub qhov (sockets), piav qhia hauv tshooj tom ntej.

Porting ntau qhov kev ua si los ntawm C ++ mus rau lub vev xaib nrog Cheerp, WebRTC thiab Firebase
Cov npe ntawm cov servers hauv qhov kev ua si thiab ntawm nplooj ntawv home

Kev ua ntawm cov qhov (socket).

Peb xav tsim ib qho API uas nyob ze rau Posix UDP Sockets kom txo tau cov kev hloov pauv uas xav tau.

Peb kuj xav siv qhov tsim nyog yam tsawg kawg nkaus uas yuav tsum tau ua rau kev sib pauv cov ntaub ntawv yooj yim tshaj hauv lub network.

Piv txwv li, peb tsis xav tau kev sib tw tiag tiag: txhua tus phooj ywg nyob ntawm tib "virtual LAN" cuam tshuam nrog qee qhov piv txwv ntawm Firebase database.

Yog li ntawd, peb tsis xav tau cov chaw nyob IP tshwj xeeb: qhov tseem ceeb ntawm Firebase qhov tseem ceeb (zoo ib yam li cov npe sau npe) txaus los txheeb xyuas cov phooj ywg, thiab txhua tus phooj ywg hauv zos muab "fake" IP chaw nyob rau txhua tus yuam sij uas yuav tsum tau muab txhais. Qhov no tshem tawm tag nrho qhov xav tau rau kev xa tawm IP chaw nyob thoob ntiaj teb, uas yog txoj haujlwm tsis tseem ceeb.

Nov yog qhov tsawg kawg nkaus API peb xav tau los siv:

// 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 yog qhov yooj yim thiab zoo ib yam li Posix Sockets API, tab sis muaj qee qhov sib txawv tseem ceeb: loging callbacks, muab IPs hauv zos, thiab tub nkeeg sib txuas.

Sau npe Callbacks

Txawm hais tias thawj qhov kev pab cuam siv tsis thaiv I / O, cov cai yuav tsum tau rov ua dua los khiav hauv lub web browser.

Yog vim li cas rau qhov no yog qhov kev tshwm sim voj nyob rau hauv browser yog muab zais los ntawm qhov kev pab cuam (xws li JavaScript los yog WebAssembly).

Hauv ib puag ncig ib puag ncig peb tuaj yeem sau cov lej zoo li no

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

Yog hais tias qhov kev tshwm sim voj yog muab zais rau peb, ces peb yuav tsum tig nws mus rau hauv ib yam dab tsi zoo li no:

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

Txoj haujlwm IP hauv zos

Cov node IDs hauv peb "network" tsis yog IP chaw nyob, tab sis Firebase yuam sij (lawv yog cov hlua uas zoo li no: -LmEC50PYZLCiCP-vqde ).

Qhov no yog qhov yooj yim vim tias peb tsis xav tau lub tshuab rau kev muab IPs thiab tshuaj xyuas lawv qhov tshwj xeeb (nrog rau kev pov tseg ntawm lawv tom qab tus neeg siv khoom disconnects), tab sis feem ntau nws yog ib qho tsim nyog los txheeb xyuas cov phooj ywg los ntawm tus lej lej.

Qhov no yog raws nraim li cas cov haujlwm yog siv rau. resolve ΠΈ reverseResolve: Daim ntawv thov twg tau txais txoj hlua tus nqi ntawm tus yuam sij (ntawm cov neeg siv tswv yim lossis ntawm tus tswv server), thiab tuaj yeem hloov mus rau qhov chaw nyob IP rau kev siv sab hauv. Tus so ntawm API kuj tau txais tus nqi no tsis yog ib txoj hlua rau kev yooj yim.

Qhov no zoo ib yam li DNS nrhiav, tab sis ua hauv zos ntawm tus neeg siv khoom.

Ntawd yog, IP chaw nyob tsis tuaj yeem sib koom ntawm cov neeg siv khoom sib txawv, thiab yog tias xav tau qee yam kev txheeb xyuas thoob ntiaj teb, nws yuav tsum tau tsim los ntawm kev sib txawv.

Tub nkeeg kev twb kev txuas

UDP tsis xav tau kev sib txuas, tab sis raws li peb tau pom, WebRTC yuav tsum muaj kev sib txuas ntev ua ntej nws tuaj yeem pib xa cov ntaub ntawv ntawm ob tus phooj ywg.

Yog tias peb xav muab tib theem ntawm abstraction, (sendto/recvfrom nrog cov phooj ywg tsis txaus ntseeg yam tsis muaj kev sib txuas ua ntej), tom qab ntawd lawv yuav tsum ua qhov "tub nkeeg" (ntev) kev sib txuas hauv API.

Nov yog qhov tshwm sim thaum muaj kev sib txuas lus ntawm "neeg rau zaub mov" thiab "tus neeg siv khoom" thaum siv UDP, thiab peb lub tsev qiv ntawv yuav tsum ua li cas:

  • Server hu bind()qhia rau lub operating system tias nws xav tau cov pob khoom ntawm qhov chaw nres nkoj.

Hloov chaw, peb yuav tshaj tawm qhov chaw nres nkoj qhib rau Firebase hauv qab tus yuam sij server thiab mloog cov xwm txheej hauv nws cov ntoo.

  • Server hu recvfrom(), txais cov pob khoom los ntawm ib tus tswv tsev ntawm qhov chaw nres nkoj no.

Hauv peb qhov xwm txheej, peb yuav tsum tau kuaj xyuas cov kab ntawv tuaj ntawm cov pob ntawv xa mus rau qhov chaw nres nkoj no.

Txhua qhov chaw nres nkoj muaj nws tus kheej kab, thiab peb ntxiv cov chaw nres nkoj thiab cov chaw nres nkoj mus rau qhov pib ntawm WebRTC datagrams kom peb paub tias kab twg yuav xa mus rau thaum lub pob ntawv tshiab tuaj txog.

Kev hu tsis yog thaiv, yog li yog tias tsis muaj pob ntawv, peb tsuas yog rov qab -1 thiab teeb tsa errno=EWOULDBLOCK.

  • Tus neeg siv tau txais IP thiab chaw nres nkoj ntawm cov neeg rau zaub mov los ntawm qee txoj kev sab nraud, thiab hu sendto(). Qhov no kuj ua rau kev hu xov tooj sab hauv. bind(), yog li ntawd tom qab recvfrom() yuav tau txais cov lus teb yam tsis tau qhia meej txog kev khi.

Hauv peb qhov xwm txheej, tus neeg siv khoom sab nraud tau txais txoj hlua tseem ceeb thiab siv cov haujlwm resolve() kom tau txais tus IP chaw nyob.

Lub sijhawm no, peb pib sib tuav tes WebRTC yog tias ob tus phooj ywg tseem tsis tau txuas nrog ib leeg. Kev sib txuas rau cov chaw nres nkoj sib txawv ntawm tib cov phooj ywg siv tib lub WebRTC DataChannel.

Peb kuj ua indirect bind()kom cov neeg rau zaub mov tuaj yeem txuas rau tom ntej sendto() nyob rau hauv rooj plaub nws kaw rau qee yam.

Tus neeg rau zaub mov tau ceeb toom ntawm tus neeg siv khoom sib txuas thaum tus neeg siv sau nws qhov kev thov SDP nyob rau hauv cov ntaub ntawv chaw nres nkoj server hauv Firebase, thiab cov neeg rau zaub mov teb nrog nws cov lus teb nyob ntawd.

Daim duab hauv qab no qhia txog qhov piv txwv ntawm cov lus ntws rau lub tswv yim lub qhov (socket) thiab kev sib kis ntawm thawj cov lus los ntawm tus neeg siv khoom mus rau lub server:

Porting ntau qhov kev ua si los ntawm C ++ mus rau lub vev xaib nrog Cheerp, WebRTC thiab Firebase
Ua kom tiav daim duab ntawm theem kev sib txuas ntawm cov neeg siv khoom thiab cov neeg rau zaub mov

xaus

Yog tias koj tau nyeem tam sim no, tej zaum koj yuav xav pom qhov kev xav hauv kev nqis tes ua. Qhov kev ua si tuaj yeem ua si ntawm teeworlds.leaningtech.com, sim nws!


Kev phooj ywg sib tw ntawm cov npoj yaig

Lub network tsev qiv ntawv code yog pub dawb muaj nyob ntawm github. Koom nrog kev sib tham ntawm peb channel ntawm Gitter!

Tau qhov twg los: www.hab.com

Ntxiv ib saib