Kuyika masewera osewera ambiri kuchokera ku C++ kupita pa intaneti ndi Cheerp, WebRTC ndi Firebase

Mau oyamba

kampani yathu Leaning Technologies imapereka njira zothetsera kusamutsa mapulogalamu apakompyuta pa intaneti. Wopanga C ++ wathu chisangalalo imapanga kuphatikiza kwa WebAssembly ndi JavaScript, yomwe imapereka zonse ziwiri yosavuta msakatuli kucheza, ndi magwiridwe antchito apamwamba.

Monga chitsanzo cha ntchito yake, tidaganiza zoyika masewera ambiri pa intaneti ndikusankha Teeworlds. Teeworlds ndi masewera ambiri a XNUMXD retro okhala ndi gulu laling'ono koma lachangu la osewera (kuphatikiza ine!). Ndi yaying'ono potengera zomwe zidatsitsidwa komanso zofunikira za CPU ndi GPU - munthu woyenera.

Kuyika masewera osewera ambiri kuchokera ku C++ kupita pa intaneti ndi Cheerp, WebRTC ndi Firebase
Kuthamanga mu msakatuli wa Teeworlds

Tinaganiza zogwiritsa ntchito polojekitiyi poyesa njira zothetsera kusamutsa ma code pa intaneti. Izi kawirikawiri zimachitika m'njira zotsatirazi:

  • XMLHttpRequest/fetch, ngati gawo la netiweki lili ndi zopempha za HTTP zokha, kapena
  • WebSoketi.

Mayankho onsewa amafunikira kuchititsa gawo la seva kumbali ya seva, ndipo siziloleza kugwiritsidwa ntchito ngati njira yoyendera UDP. Izi ndizofunikira pamapulogalamu anthawi yeniyeni monga mapulogalamu amisonkhano yamakanema ndi masewera, chifukwa zimatsimikizira kuperekedwa ndi dongosolo la mapaketi a protocol. TCP zitha kukhala cholepheretsa kuchepa kwa latency.

Pali njira yachitatu - gwiritsani ntchito netiweki kuchokera pa msakatuli: WebRTC.

RTCDataChannel Imathandizira kufalitsa kodalirika komanso kosadalirika (pambuyo pake imayesa kugwiritsa ntchito UDP ngati njira yoyendera ngati kuli kotheka), ndipo ingagwiritsidwe ntchito zonse ndi seva yakutali komanso pakati pa asakatuli. Izi zikutanthauza kuti titha kuyika pulogalamu yonse ku msakatuli, kuphatikiza gawo la seva!

Komabe, izi zimabwera ndi zovuta zina: anzako awiri a WebRTC asanalankhule, amayenera kugwirana chanza chovuta kwambiri kuti agwirizane, zomwe zimafunikira mabungwe angapo a chipani chachitatu (seva yolumikizira ndi seva imodzi kapena zingapo. STUN/Tembenuzani).

Moyenera, tikufuna kupanga netiweki API yomwe imagwiritsa ntchito WebRTC mkati, koma ili pafupi kwambiri ndi mawonekedwe a UDP Sockets omwe safunikira kukhazikitsa kulumikizana.

Izi zitilola kugwiritsa ntchito mwayi pa WebRTC popanda kuwonetsa zovuta pama code ogwiritsira ntchito (omwe timafuna kusintha pang'ono momwe tingathere pantchito yathu).

Zochepa za WebRTC

WebRTC ndi gulu la ma API omwe akupezeka mu asakatuli omwe amapereka kufalitsa kwa anzanu ndi anzawo kumawu, makanema ndi data mosasamala.

Kulumikizana pakati pa anzawo kumakhazikitsidwa (ngakhale pali NAT mbali imodzi kapena mbali zonse ziwiri) pogwiritsa ntchito ma seva a STUN ndi/kapena TURN kudzera mu makina otchedwa ICE. Anzathu amasinthanitsa zidziwitso za ICE ndi magawo amakanema kudzera pakupereka ndi yankho la protocol ya SDP.

Oo! Ndi zidule zingati panthawi imodzi? Tiyeni tifotokoze mwachidule tanthauzo la mawu awa:

  • Session Traversal Utilities kwa NAT (STUN) - ndondomeko yodutsa NAT ndikupeza awiri (IP, port) posinthanitsa deta mwachindunji ndi wolandirayo. Ngati akwanitsa kumaliza ntchito yake, anzake akhoza kusinthanitsa deta wina ndi mzake.
  • Kudutsa Pogwiritsa Ntchito Ma Relay kuzungulira NAT (Tembenuzani) imagwiritsidwanso ntchito podutsa NAT, koma imagwiritsa ntchito izi potumiza deta kudzera pa proxy yomwe imawonekera kwa anzawo onse. Imawonjezera latency ndipo ndiyokwera mtengo kwambiri kuti igwiritse ntchito kuposa STUN (chifukwa imagwiritsidwa ntchito panthawi yonse yolankhulana), koma nthawi zina ndiyo njira yokhayo.
  • Kukhazikitsa kwa Interactive Connectivity (ayezi) amagwiritsidwa ntchito posankha njira yabwino kwambiri yolumikizira anzawo awiri potengera zomwe apeza kuchokera kulumikiza anzawo mwachindunji, komanso chidziwitso cholandilidwa ndi nambala iliyonse ya ma seva a STUN ndi TURN.
  • Ndondomeko Yofotokozera Gawo (RDS) ndi mawonekedwe ofotokozera magawo a njira zolumikizira, mwachitsanzo, ofuna ICE, ma codec a multimedia (pankhani ya audio / kanema kanema), ndi zina ... Mmodzi mwa anzawo amatumiza SDP Kupereka, ndipo wachiwiri akuyankha ndi SDP Yankho. . . Pambuyo pake, njira imapangidwa.

Kuti apange kulumikizana koteroko, anzawo ayenera kusonkhanitsa zomwe amalandira kuchokera ku ma seva a STUN ndi TURN ndikusinthanitsa wina ndi mnzake.

Vuto ndiloti iwo alibe mphamvu yolankhulana mwachindunji, kotero kuti makina otuluka kunja kwa gulu ayenera kukhalapo kuti asinthe deta iyi: seva yowonetsera.

Seva yowonetsera ikhoza kukhala yophweka kwambiri chifukwa ntchito yake yokha ndiyo kutumiza deta pakati pa anzanu mu gawo la kugwirana chanza (monga momwe tawonetsera pa chithunzi pansipa).

Kuyika masewera osewera ambiri kuchokera ku C++ kupita pa intaneti ndi Cheerp, WebRTC ndi Firebase
Chithunzi chosavuta cha WebRTC chogwirana chanza

Teeworlds Network Model mwachidule

Zomangamanga zama network a Teeworlds ndizosavuta:

  • Makasitomala ndi magawo a seva ndi mapulogalamu awiri osiyana.
  • Makasitomala amalowa mumasewerawa polumikizana ndi imodzi mwama seva angapo, iliyonse yomwe imakhala ndi masewera amodzi panthawi imodzi.
  • Kutumiza kwa data konse mumasewera kumachitika kudzera pa seva.
  • Seva yapadera yapadera imagwiritsidwa ntchito kusonkhanitsa mndandanda wa ma seva onse omwe amawonetsedwa mu kasitomala wamasewera.

Chifukwa cha kugwiritsa ntchito WebRTC pakusinthana kwa data, titha kusamutsa gawo la seva lamasewera ku msakatuli komwe kasitomala ali. Izi zimatipatsa mwayi waukulu ...

Chotsani ma seva

Kusowa kwa malingaliro a seva kuli ndi mwayi wabwino: titha kuyika pulogalamu yonseyo ngati zokhazikika pamasamba a Github kapena pazida zathu zomwe zili kumbuyo kwa Cloudflare, kuwonetsetsa kutsitsa mwachangu komanso nthawi yayitali kwaulere. Ndipotu, tikhoza kuiwala za iwo, ndipo ngati tili ndi mwayi ndipo masewerawa amakhala otchuka, ndiye kuti zomangamanga siziyenera kukhala zamakono.

Komabe, kuti dongosololi ligwire ntchito, tiyenerabe kugwiritsa ntchito zomangamanga zakunja:

  • Seva imodzi kapena zingapo za STUN: Tili ndi zosankha zingapo zaulere zomwe mungasankhe.
  • Osachepera seva imodzi ya TURN: palibe zosankha zaulere pano, kotero titha kukhazikitsa zathu kapena kulipira ntchitoyo. Mwamwayi, nthawi zambiri kugwirizana kungakhazikitsidwe kupyolera mu ma seva a STUN (ndikupereka p2p yeniyeni), koma TURN ikufunika ngati njira yobwereranso.
  • Seva Yoyimba: Mosiyana ndi zina ziwirizi, kusaina sikuli kofanana. Zomwe seva yosainira idzakhala nayo kwenikweni zimatengera pulogalamuyo. Kwa ife, musanayambe kugwirizanitsa, m'pofunika kusinthanitsa pang'ono deta.
  • Teeworlds Master Server: Imagwiritsidwa ntchito ndi maseva ena kulengeza kukhalapo kwawo komanso makasitomala kuti apeze ma seva aboma. Ngakhale sizofunikira (makasitomala amatha kulumikizana ndi seva yomwe amawadziwa pamanja), zingakhale bwino kukhala ndi osewera kuti achite nawo masewera ndi anthu mwachisawawa.

Tinaganiza zogwiritsa ntchito maseva aulere a STUN a Google, ndikudzipatulira tokha seva imodzi ya TURN.

Kwa mfundo ziwiri zomaliza zomwe tidagwiritsa ntchito Kutentha:

  • Seva ya Teeworlds master imayendetsedwa mosavuta: monga mndandanda wazinthu zomwe zili ndi chidziwitso (dzina, IP, mapu, mode, ...) pa seva iliyonse yogwira. Ma seva amasindikiza ndikusintha zinthu zawo, ndipo makasitomala amatenga mndandanda wonse ndikuuwonetsa kwa osewera. Timawonetsanso mndandanda patsamba loyambira ngati HTML kuti osewera angodinanso pa seva ndikutengedwera kumasewerawo.
  • Kuyika chizindikiro kumagwirizana kwambiri ndi kukhazikitsa kwathu zitsulo, zomwe zafotokozedwa mu gawo lotsatira.

Kuyika masewera osewera ambiri kuchokera ku C++ kupita pa intaneti ndi Cheerp, WebRTC ndi Firebase
Mndandanda wa maseva mkati mwamasewera komanso patsamba loyambira

Kukhazikitsidwa kwa sockets

Tikufuna kupanga API yomwe ili pafupi ndi Posix UDP Sockets momwe tingathere kuti tichepetse chiwerengero cha zosintha zofunika.

Tikufunanso kukhazikitsa zochepera zofunika pakusinthana kosavuta kwa data pamanetiweki.

Mwachitsanzo, sitifunika njira yeniyeni: anzanu onse ali pa "LAN yeniyeni" yomwe imagwirizanitsidwa ndi zochitika zapadera za Firebase.

Chifukwa chake, sitifunika ma adilesi apadera a IP: makiyi apadera a Firebase (ofanana ndi mayina a madambwe) ndiwokwanira kuzindikira anzawo, ndipo mnzako aliyense wakomweko amagawira ma adilesi a IP "abodza" ku kiyi iliyonse yomwe ikufunika kumasuliridwa. Izi zimathetseratu kufunika kogawa adilesi ya IP padziko lonse lapansi, yomwe ndi ntchito yosachepera.

Nayi API yochepera yomwe tikuyenera kukhazikitsa:

// 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 ndiyosavuta komanso yofanana ndi Posix Sockets API, koma ili ndi zosiyana zingapo zofunika: kudula mitengo, kugawa ma IP akomweko, ndi kulumikizana kwaulesi.

Kulembetsa Ma Callbacks

Ngakhale pulogalamu yoyambirira imagwiritsa ntchito I/O yosatsekereza, code iyenera kusinthidwanso kuti iyendetse pa msakatuli.

Chifukwa cha izi ndikuti kuzungulira kwa zochitika mu msakatuli kumabisika ku pulogalamuyi (ikhale JavaScript kapena WebAssembly).

M'malo achibadwidwe tikhoza kulemba code monga chonchi

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

Ngati chochitikacho chikubisidwa kwa ife, ndiye kuti tiyenera kuchisintha kukhala chonchi:

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

Kugawa kwa IP komweko

Ma ID a node mu "network" yathu si ma adilesi a IP, koma makiyi a Firebase (ndi zingwe zomwe zimawoneka chonchi: -LmEC50PYZLCiCP-vqde ).

Izi ndizosavuta chifukwa sitifunika njira yoperekera ma IP ndikuwona kuti ndi osiyana (komanso kuwataya kasitomala akataya), koma nthawi zambiri ndikofunikira kuzindikira anzawo potengera manambala.

Izi ndizomwe zimagwiritsidwa ntchito. resolve ΠΈ reverseResolve: Kugwiritsa ntchito mwanjira ina kumalandira mtengo wa kiyi (kudzera mwa wogwiritsa ntchito kapena kudzera pa seva ya master), ndipo imatha kuyisintha kukhala adilesi ya IP kuti igwiritsidwe ntchito mkati. Ena onse a API amalandiranso mtengo uwu m'malo mwa chingwe chosavuta.

Izi ndizofanana ndi kuyang'ana kwa DNS, koma kumachitidwa kwanuko kwa kasitomala.

Ndiko kuti, ma adilesi a IP sangathe kugawidwa pakati pa makasitomala osiyanasiyana, ndipo ngati mtundu wina wa chizindikiritso chapadziko lonse lapansi ukufunika, uyenera kupangidwa mwanjira ina.

Kulumikizana kwaulesi

UDP sifunikira kulumikizana, koma monga tawonera, WebRTC imafuna njira yayitali yolumikizira isanayambe kusamutsa deta pakati pa anzawo awiri.

Ngati tikufuna kupereka mulingo womwewo wochotsa, (sendto/recvfrom ndi anzawo osagwirizana popanda kugwirizana koyambirira), ndiye kuti ayenera kuchita "ulesi" (kuchedwa) kugwirizana mkati mwa API.

Izi ndi zomwe zimachitika pakulankhulana kwanthawi zonse pakati pa "seva" ndi "kasitomala" akamagwiritsa ntchito UDP, ndi zomwe laibulale yathu iyenera kuchita:

  • Kuyimba kwa seva bind()kuuza opareshoni kuti akufuna kulandira mapaketi pa doko lotchulidwa.

M'malo mwake, tidzasindikiza doko lotseguka ku Firebase pansi pa kiyi ya seva ndikumvetsera zochitika mumzere wake waung'ono.

  • Kuyimba kwa seva recvfrom(), kuvomereza mapaketi obwera kuchokera kwa wolandira aliyense padoko ili.

Kwa ife, tifunika kuyang'ana mzere womwe ukubwera wa mapaketi omwe amatumizidwa ku doko ili.

Doko lirilonse liri ndi mzere wake, ndipo timawonjezera magwero ndi madoko kumayambiriro kwa ma datagram a WebRTC kuti tidziwe mzere woti titumize paketi yatsopano ikafika.

Kuyimbako sikutsekereza, kotero ngati palibe mapaketi, timangobwerera -1 ndikuyika errno=EWOULDBLOCK.

  • Wothandizira amalandira IP ndi doko la seva ndi njira zina zakunja, ndi mafoni sendto(). Izi zimapanganso kuyimba kwamkati. bind(), chifukwa chake chotsatira recvfrom() adzalandira yankho popanda kulumikiza mwachindunji.

Kwa ife, kasitomala kunja amalandira chinsinsi cha chingwe ndikugwiritsa ntchito ntchitoyi resolve() kuti mupeze adilesi ya IP.

Panthawiyi, timayambitsa kugwirana chanza kwa WebRTC ngati anzawo awiriwa sanagwirizane. Kulumikizana kumadoko osiyanasiyana a anzawo omwewo amagwiritsa ntchito WebRTC DataChannel yomweyo.

Timachitanso mosalunjika bind()kotero kuti seva ikhoza kulumikizananso motsatira sendto() ngati idatsekedwa pazifukwa zina.

Seva imadziwitsidwa za kulumikizidwa kwa kasitomala pamene kasitomala akulemba zopereka zake za SDP pansi pa chidziwitso cha seva ku Firebase, ndipo seva imayankha ndi yankho lake pamenepo.

Chithunzi chomwe chili pansipa chikuwonetsa chitsanzo cha kayendedwe ka uthenga kwa socket scheme ndi kutumiza uthenga woyamba kuchokera kwa kasitomala kupita ku seva:

Kuyika masewera osewera ambiri kuchokera ku C++ kupita pa intaneti ndi Cheerp, WebRTC ndi Firebase
Chithunzi chathunthu cha gawo lolumikizana pakati pa kasitomala ndi seva

Pomaliza

Ngati mwawerenga mpaka pano, mwina mungakonde kuwona chiphunzitsocho chikugwira ntchito. Masewerawa atha kuseweredwa teeworlds.leaningtech.com, yesani!


Masewera aubwenzi pakati pa anzawo

Khodi ya library library imapezeka kwaulere ku Github. Lowani nawo zokambirana pa tchanelo chathu pa Gitter!

Source: www.habr.com

Kuwonjezera ndemanga