Ukuhambisa umdlalo wabadlali abaninzi ukusuka kwiC++ ukuya kwiwebhu ngeCheerp, WebRTC kunye neFirebase

Intshayelelo

inkampani yethu I-Leaning Technologies ibonelela ngezisombululo zokufaka izicelo zedesktop zesiqhelo kwiwebhu. Umqokeleli wethu we-C++ chwayita yenza indibaniselwano yeWebAssembly kunye neJavaScript, ebonelela ngazo zombini ibrowser intsebenziswano elula, kunye nokusebenza okuphezulu.

Njengomzekelo wesicelo sayo, sigqibe kwelokuba sikhuphe umdlalo wabadlali abaninzi kwiwebhu kwaye sikhethe Ulutsha. I-Teeworlds ngumdlalo wabadlali abaninzi we-2D retro kunye noluntu oluncinci kodwa olusebenzayo lwabadlali (kubandakanywa nam!). Incinci zombini ngokwezixhobo ezikhutshelweyo kunye neemfuno ze-CPU kunye ne-GPU-umgqatswa ofanelekileyo.

Ukuhambisa umdlalo wabadlali abaninzi ukusuka kwiC++ ukuya kwiwebhu ngeCheerp, WebRTC kunye neFirebase
Ukubaleka kwi-browser yeTeeworlds

Sagqiba ekubeni sisebenzise le projekthi ukwenza umfuniselo izisombululo jikelele zothungelwano ikhowudi womnatha kwi web. Oku kuqhele ukwenziwa ngezi ndlela zilandelayo:

  • XMLHttpRequest/landa, ukuba indawo yothungelwano iqulathe kuphela izicelo zeHTTP, okanye
  • IWebSocket.

Zombini izisombululo zifuna ukubamba icandelo leseva kwicala lomncedisi, kwaye azivumeli ukusetyenziswa njengeprotocol yothutho UDP. Oku kubalulekile kwizicelo zexesha langempela ezifana nesoftware yenkomfa yevidiyo kunye nemidlalo, kuba iqinisekisa ukuhanjiswa kunye nomyalelo weepakethi zeprotocol. TCP inokuba ngumqobo kwi-low latency.

Kukho indlela yesithathu - sebenzisa inethiwekhi ukusuka kwisikhangeli: WebRTC.

RTCDataChannel Ixhasa ukuhanjiswa okuthembekileyo kunye nokungathembekiyo (kwimeko yokugqibela izama ukusebenzisa i-UDP njengeprotocol yezothutho nanini na kunokwenzeka), kwaye ingasetyenziselwa zombini kunye nomncedisi ode kunye naphakathi kweziphequluli. Oku kuthetha ukuba singakwazi ukufaka isicelo sonke kwisikhangeli, kuquka necandelo leseva!

Nangona kunjalo, oku kuza nobunzima obongezelelweyo: phambi kokuba oontanga ababini beWebRTC banxibelelane, kufuneka benze ukuxhawulana ngesandla okuntsokothileyo ukudibanisa, nto leyo efuna amaziko aliqela lesithathu (iseva yokubonisa kunye neseva enye okanye ngaphezulu. I-STUN/JIKA).

Ngokufanelekileyo, singathanda ukwenza i-API yenethiwekhi esebenzisa i-WebRTC ngaphakathi, kodwa isondele kangangoko kwi-interface ye-UDP Sockets engadingi kuseka uxhumano.

Oku kuya kusivumela ukuba sisebenzise iWebRTC ngaphandle kokubeka iinkcukacha ezinzima kwikhowudi yesicelo (esifuna ukuyitshintsha kancinci kangangoko kwiprojekthi yethu).

Ubuncinci beWebRTC

I-WebRTC yiseti yee-APIs ezifumaneka kwiziphequluli ezibonelela ngokuhanjiswa koontanga-koontanga beaudio, ividiyo kunye nedatha engafanelekanga.

Uqhagamshelwano phakathi koontanga lusekiwe (nokuba kukho i-NAT kwelinye okanye macala omabini) kusetyenziswa i-STUN kunye/okanye iiseva ze-TURN ngendlela ebizwa ngokuba yi-ICE. Abalingane batshintshiselana ngolwazi lwe-ICE kunye neeparamitha zetshaneli ngokunikezela kunye nempendulo yeprotocol ye-SDP.

Wowu! Zingaphi izifinyezo ngexesha elinye? Makhe sichaze ngokufutshane ukuba la magama athetha ukuthini:

  • ISeshini yokuNqulela izinto eziluncedo ze-NAT (I-STUN) - iprotocol yokudlula i-NAT kunye nokufumana iperi (IP, izibuko) yokutshintshiselana ngedatha ngokuthe ngqo nomninimzi. Ukuba uyakwazi ukugqiba umsebenzi wakhe, ngoko oontanga banokutshintshana ngokuzimeleyo idatha kunye nomnye.
  • UkuHamba usebenzisa iiRelays ezijikeleze i-NAT (JIKA) Ikwasetyenziswa kwi-NAT traversal, kodwa iphumeza oku ngokuthumela idatha ngeproksi ebonakala kubo bobabini abalingane. Yongeza i-latency kwaye ibiza kakhulu ukuphumeza kune-STUN (kuba isetyenziswe kuyo yonke iseshoni yonxibelelwano), kodwa ngamanye amaxesha yiyona ndlela kuphela.
  • Ukusekwa koQhagamshelwano oluSebenzayo (ICE) isetyenziselwa ukukhetha eyona ndlela ingcono yokudibanisa oontanga ababini ngokusekelwe kulwazi olufunyenwe ngokudibanisa oontanga ngokuthe ngqo, kunye nolwazi olufunyenweyo naliphi na inani leeseva ze-STUN kunye ne-TURN.
  • Inkqubo yeNkcazelo yeSeshini (RDS) yifomathi yokuchaza iiparameters zetshaneli zoqhagamshelwano, umzekelo, abaviwa be-ICE, i-multimedia codecs (kwimeko yesiteshi somsindo / ividiyo), njl. . Emva koku, itshaneli yenziwa.

Ukwenza uxhulumaniso olunjalo, oontanga kufuneka baqokelele ulwazi abalufumana kwi-STUN kunye ne-TURN abancedisi kwaye batshintshisane omnye nomnye.

Ingxaki kukuba abakakwazi ukunxibelelana ngokuthe ngqo, ngoko ke kufuneka kubekho indlela engaphandle kwebhendi yokutshintshiselana ngale datha: iseva yokubonisa.

Umncedisi womqondiso unokuba lula kakhulu kuba umsebenzi wakhe kuphela kukudlulisa idatha phakathi koontanga kwisigaba sokuxhawula izandla (njengoko kuboniswe kumzobo ongezantsi).

Ukuhambisa umdlalo wabadlali abaninzi ukusuka kwiC++ ukuya kwiwebhu ngeCheerp, WebRTC kunye neFirebase
I-WebRTC eyenziwe lula idiagram yolandelelwano lokuxhawula isandla

Umboniso weModeli yeTeeworlds Network

Uyilo lwenethiwekhi yeTeeworlds ilula kakhulu:

  • Umxhasi kunye namacandelo omncedisi zinkqubo ezimbini ezahlukeneyo.
  • Abathengi bangena kumdlalo ngokuqhagamshela kwenye yeeseva ezininzi, nganye kuzo ibamba umdlalo omnye ngexesha.
  • Lonke ugqithiso lwedatha kumdlalo lwenziwa ngomncedisi.
  • I-master server ekhethekileyo isetyenziselwa ukuqokelela uluhlu lwazo zonke iiseva zoluntu eziboniswa kumthengi womdlalo.

Ngombulelo ekusebenziseni iWebRTC yotshintshiselwano lwedatha, sinokudlulisela icandelo leseva yomdlalo kwisikhangeli apho umthengi akhoyo. Oku kusinika ithuba elikhulu...

Lahla iiseva

Ukungabikho kwengqiqo yeseva kunenzuzo enhle: sinokuhambisa sonke isicelo njengomxholo ongatshintshiyo kumaphepha eGithub okanye kwi-hardware yethu emva kwe-Cloudflare, ngaloo ndlela siqinisekisa ukukhuphela ngokukhawuleza kunye nexesha eliphezulu lokukhulula. Ngapha koko, sinokulibala ngabo, kwaye ukuba sinethamsanqa kwaye umdlalo uyathandwa, ke iziseko aziyi kufuneka zenziwe zanamhlanje.

Nangona kunjalo, ukuze inkqubo isebenze, kusafuneka sisebenzise uyilo lwangaphandle:

  • Iseva enye okanye ngaphezulu kwe-STUN: Sineendlela ezininzi zokukhetha zasimahla esinokukhetha kuzo.
  • Ubuncinci iseva enye ye-TURN: akukho zikhetho zasimahla apha, ngoko ke sinokuseta ezethu okanye sihlawulele inkonzo. Ngethamsanqa, ixesha elininzi uxhulumaniso lunokusekwa ngokusebenzisa abancedisi be-STUN (kwaye unikeze i-p2p eyinyani), kodwa i-TURN iyadingeka njengokhetho lokubuyela umva.
  • Iseva Yomqondiso: Ngokungafaniyo neminye imiba emibini, umqondiso awubekwanga emgangathweni. Oko umncedisi womqondiso uya kuba noxanduva lwakhe kuxhomekeke noko kwisicelo. Kwimeko yethu, ngaphambi kokuseka uxhumano, kuyimfuneko ukutshintshisa inani elincinci ledatha.
  • I-Teeworlds Master Server: Isetyenziswa zezinye iiseva ukubhengeza ubukho bazo kunye nabathengi ukufumana iiseva zoluntu. Nangona kungafunekiyo (abaxumi banokuhlala beqhagamshela kumncedisi ababaziyo ngesandla), kuya kuba kuhle ukuba ukuze abadlali bathathe inxaxheba kwimidlalo nabantu abangakhethiyo.

Sigqibe ekubeni sisebenzise iiseva zikaGoogle ze-STUN zasimahla, kwaye sasebenzisa iseva enye ye-TURN ngokwethu.

Kumanqaku amabini okugqibela siwasebenzisile Firebase:

  • I-Teeworlds master server iphunyezwa ngokulula kakhulu: njengoluhlu lwezinto eziqulethe ulwazi (igama, i-IP, imephu, indlela, ...) yomncedisi ngamnye osebenzayo. Abancedisi bapapashe kwaye bahlaziye into yabo, kwaye abathengi bathathe lonke uluhlu kwaye babonise kumdlali. Sikwabonisa uluhlu kwiphepha lasekhaya njengeHTML ukuze abadlali bacofe ngokulula kwiseva kwaye basiwe ngqo kumdlalo.
  • Umqondiso uhambelana ngokusondeleyo nokuphunyezwa kweesokethi zethu, ezichazwe kwicandelo elilandelayo.

Ukuhambisa umdlalo wabadlali abaninzi ukusuka kwiC++ ukuya kwiwebhu ngeCheerp, WebRTC kunye neFirebase
Uluhlu lweeseva ngaphakathi komdlalo nakwiphepha lasekhaya

Ukuphunyezwa kweziseko

Sifuna ukwenza i-API ekufutshane ne-Posix UDP Sockets kangangoko kunokwenzeka ukunciphisa inani lotshintsho olufunekayo.

Sikwafuna ukuphumeza ubuncinci obufunekayo kutshintshiselwano lwedatha olulula kwinethiwekhi.

Umzekelo, asiyidingi indlela yokwenyani: zonke iintanga ziku-"virtual LAN" enye enxulumene nomzekelo othile wesiseko sedatha ye-Firebase.

Ke ngoko, asidingi dilesi ye-IP eyodwa: amaxabiso abalulekileyo e-Firebase (afana namagama esizinda) anele ukuchonga oontanga, kwaye intanga nganye ekuhlaleni inika iidilesi ze-IP "zomgunyathi" kwisitshixo ngasinye ekufuneka siguqulelwe. Oku kuphelisa ngokupheleleyo imfuno yokunikezelwa kwedilesi ye-IP yehlabathi jikelele, engumsebenzi ongeyonto encinci.

Nantsi eyona API incinci ekufuneka siyiphumeze:

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

I-API ilula kwaye iyafana nePosix Sockets API, kodwa inomahluko obalulekileyo ambalwa: ukuloga ii-callbacks, ukwabela ii-IP zasekhaya, kunye noqhagamshelo olonqenayo.

Ukubhalisa ii-Callbacks

Nokuba inkqubo yokuqala isebenzisa i-I / O engathinteliyo, ikhowudi kufuneka ihlaziywe ukuze isebenze kwisiphequluli sewebhu.

Isizathu salokhu kukuba i-loop yesiganeko kwisiphequluli ifihliwe kwiprogram (ingaba yiJavaScript okanye iWebAssembly).

Kwimeko-bume yendalo singabhala ikhowudi ngolu hlobo

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

Ukuba i-loop yesiganeko ifihliwe kuthi, ngoko kufuneka siyiguqule ibe yinto enje:

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

Isabelo se-IP yendawo

Ii-ID ze-node "kwinethiwekhi" yethu ayizodilesi ze-IP, kodwa izitshixo ze-Firebase (ziintambo ezijongeka ngolu hlobo: -LmEC50PYZLCiCP-vqde ).

Oku kulungele kuba asidingi sixhobo sokunika ii-IP kunye nokujonga ukungafani kwazo (kunye nokuzilahla emva kokuba umxhasi eqhawule uqhagamshelwano), kodwa kudla ngokuba yimfuneko ukuchonga oontanga ngexabiso lamanani.

Yile nto kanye esetyenziselwa yona imisebenzi. resolve и reverseResolve: Isicelo ngandlela ithile sifumana ixabiso lomtya wesitshixo (ngegalelo lomsebenzisi okanye nge-master server), kwaye singayiguqulela kwidilesi ye-IP yokusetyenziswa kwangaphakathi. Enye i-API iphinda ifumane eli xabiso endaweni yomtya wokulula.

Oku kufana nojongo lwe-DNS, kodwa yenziwa ekuhlaleni kumxhasi.

Oko kukuthi, iidilesi ze-IP azinakwabelwana ngazo phakathi kwabathengi abahlukeneyo, kwaye ukuba uhlobo oluthile lwesazisi sehlabathi luyafuneka, kuya kufuneka lwenziwe ngendlela eyahlukileyo.

Uqhagamshelo lobuvila

I-UDP ayifuni uxhulumaniso, kodwa njengoko sibonile, iWebRTC idinga inkqubo yoqhagamshelwano ende ngaphambi kokuba iqalise ukudlulisa idatha phakathi kweentanga ezimbini.

Ukuba sifuna ukubonelela ngenqanaba elifanayo lokuthatha, (sendto/recvfrom kunye noontanga abathintekayo ngaphandle koxhulumaniso lwangaphambili), ngoko kufuneka benze "uvila" (ukulibaziseka) uxhulumaniso ngaphakathi kwe-API.

Oku kwenzeka ngexesha lonxibelelwano oluqhelekileyo phakathi “kweseva” kunye “nomthengi” xa usebenzisa i-UDP, kunye nento ekufuneka yenziwe yithala leencwadi lethu:

  • Iifowuni zeseva bind()ukuxelela inkqubo yokusebenza ukuba ifuna ukufumana iipakethe kwizibuko elikhankanyiweyo.

Endaweni yoko, siya kupapasha izibuko elivulekileyo kwi-Firebase phantsi kwesitshixo seseva kwaye simamele iminyhadala kwi-subtree yayo.

  • Iifowuni zeseva recvfrom(), ukwamkela iipakethi ezivela kuyo nayiphi na inginginya kweli zibuko.

Kwimeko yethu, kufuneka sijonge umgca ongenayo weepakethi ezithunyelwe kule port.

Ichweba ngalinye linomgca walo, kwaye songeza umthombo kunye neendawo zokufika ekuqaleni kweedathagram zeWebRTC ukuze sazi ukuba yeyiphi umgca wokuya phambili xa ipakethe entsha ifika.

Umnxeba awuvali, ke ukuba akukho zipakethi, sibuya ngokulula -1 kwaye sisete errno=EWOULDBLOCK.

  • Umxhasi ufumana i-IP kunye nechweba lomncedisi ngeendlela ezithile zangaphandle, kunye neefowuni sendto(). Oku kwenza umnxeba wangaphakathi. bind(), ngoko kulandela recvfrom() izakufumana impendulo ngaphandle kokwenza ngokucacileyo isibophelelo.

Kwimeko yethu, umxhasi wangaphandle ufumana isitshixo somtya kwaye usebenzisa umsebenzi resolve() ukufumana idilesi ye-IP.

Ngeli xesha, siqalisa ukubambana ngesandla kweWebRTC ukuba abalingane ababini abakaqhagamshelwa omnye komnye. Uqhagamshelo kumazibuko ahlukeneyo ontanga efanayo sebenzisa i-WebRTC DataChannel efanayo.

Senza kwakhona ngokungathanga ngqo bind()ukuze umncedisi akwazi ukuqhagamshela kwakhona kokulandelayo sendto() ukuba ivalwe ngesizathu esithile.

Umncedisi uyaziswa ngoqhagamshelo lomxhasi xa umxhasi ebhala unikezelo lwakhe lwe-SDP phantsi kolwazi lwezibuko lomncedisi kwi-Firebase, kwaye iseva iphendula ngempendulo yayo apho.

Umzobo ongezantsi ubonisa umzekelo wokuhamba komyalezo weskim socket kunye nokuhanjiswa komyalezo wokuqala ukusuka kumxhasi ukuya kumncedisi:

Ukuhambisa umdlalo wabadlali abaninzi ukusuka kwiC++ ukuya kwiwebhu ngeCheerp, WebRTC kunye neFirebase
Gqibezela umzobo wesigaba soqhagamshelwano phakathi komxhasi kunye nomncedisi

isiphelo

Ukuba ufunde oku kude, mhlawumbi unomdla wokubona ithiyori isebenza. Umdlalo ungadlalwa teeworlds.leaningtech.com, yizame!


Umdlalo wobuhlobo phakathi koogxa

Ikhowudi yelayibrari yenethiwekhi ifumaneka simahla apha Github. Joyina incoko kwitshaneli yethu ku Gitter!

umthombo: www.habr.com

Yongeza izimvo