Jiri Cheerp, WebRTC na Firebase na-ebufe egwuregwu ọtụtụ mmadụ site na C++ gaa na webụ

Okwu Mmalite

ụlọ ọrụ anyị Teknụzụ dabere na-enye azịza maka ibuga ngwa desktọpụ ọdịnala na webụ. Ihe nchịkọta C++ anyị obi ụtọ na-ewepụta ngwakọta nke WebAssembly na JavaScript, nke na-enye ha abụọ mfe nchọgharị mmekọrịta, na arụmọrụ dị elu.

Dịka ọmụmaatụ nke ngwa ya, anyị kpebiri ibubata egwuregwu ọtụtụ egwuregwu na webụ wee họrọ Teeworlds. Teeworlds bụ egwuregwu retro XNUMXD ọtụtụ mmadụ nwere obere ndị egwuregwu na-arụsi ọrụ ike (gụnyere m!). Ọ dị obere ma n'ihe gbasara akụrụngwa ebudatara yana ihe achọrọ CPU na GPU - ezigbo onye ndoro-ndoro ochichi.

Jiri Cheerp, WebRTC na Firebase na-ebufe egwuregwu ọtụtụ mmadụ site na C++ gaa na webụ
Na-agba ọsọ na ihe nchọgharị Teeworlds

Anyị kpebiri iji ọrụ a mee nnwale ngwọta izugbe maka ibubata koodu netwọkụ na webụ. A na-emekarị nke a n'ụzọ ndị a:

  • Arịrịọ/ịchọta XMLHttp, ma ọ bụrụ na akụkụ netwọk nwere naanị arịrịọ HTTP, ma ọ bụ
  • ntọala webụ.

Ngwọta abụọ a chọrọ nnabata mpaghara ihe nkesa n'akụkụ ihe nkesa, ọ nweghịkwa ekwe ka ojiji dị ka usoro ụgbọ njem UDP. Nke a dị mkpa maka ngwa ngwa dị ka ngwa nzụkọ vidiyo na egwuregwu, n'ihi na ọ na-ekwe nkwa ịnyefe na usoro ngwugwu protocol. TCP nwere ike bụrụ ihe mgbochi na obere latency.

Enwere ụzọ nke atọ - jiri netwọk site na ihe nchọgharị: WebRTC.

RTCDataChannel Ọ na-akwado ma nnyefe a pụrụ ịdabere na ya na nke a na-apụghị ịdabere na ya (na nke ikpeazụ ọ na-agbalị iji UDP dị ka usoro njem mgbe ọ bụla o kwere mee), enwere ike iji ya na ihe nkesa dịpụrụ adịpụ na n'etiti ihe nchọgharị. Nke a pụtara na anyị nwere ike ibubata ngwa niile na ihe nchọgharị, gụnyere akụkụ nkesa!

Otú ọ dị, nke a na-abịa na ihe isi ike ọzọ: tupu ndị ọgbọ WebRTC abụọ enwee ike ịkparịta ụka, ha kwesịrị ịme aka aka dị mgbagwoju anya iji jikọọ, nke chọrọ ọtụtụ ụlọ ọrụ ndị ọzọ (ihe nkesa na-egosi na otu ma ọ bụ karịa sava). STUN/Gbanwee).

Dị ka o kwesịrị, anyị ga-achọ ịmepụta API netwọkụ na-eji WebRTC n'ime, mana ọ dị nso dị ka o kwere mee na UDP Sockets interface nke na-adịghị mkpa iji guzobe njikọ.

Nke a ga-enye anyị ohere iji WebRTC mee ihe na-enweghị ikpughe nkọwa dị mgbagwoju anya na koodu ngwa (nke anyị chọrọ ịgbanwe ntakịrị dị ka o kwere mee na ọrụ anyị).

WebRTC kacha nta

WebRTC bụ nhazi API dị na ihe nchọgharị na-enye nnyefe nke ndị ọgbọ na ndị ọgbọ nke ọdịyo, vidiyo na data aka ike.

Ejikọtara njikọ dị n'etiti ndị ọgbọ (ọbụlagodi ma ọ bụrụ na enwere NAT na otu ma ọ bụ abụọ) site na iji STUN na / ma ọ bụ atụgharị sava site na usoro a na-akpọ ICE. Ndị ọgbọ na-agbanwe ozi ICE na paramita ọwa site na inye na azịza nke protocol SDP.

Chaị! Kedu ndebiri ndebiri ole n'otu oge? Ka anyị kọwaa nkenke ihe okwu ndị a pụtara:

  • Oge njem njem maka NAT (STUN) - Usoro maka ịgafe NAT wee nweta ụzọ (IP, ọdụ ụgbọ mmiri) maka ịgbanwere data ozugbo na onye ọbịa. Ọ bụrụ na ọ jisiri ike rụchaa ọrụ ya, mgbe ahụ ndị ọgbọ nwere ike ịgbanwe data onwe ha n'onwe ha.
  • Njegharị Iji Relays gburugburu NAT (Gbanwee) A na-ejikwa NAT traversal, mana ọ na-eme nke a site na ibuga data site na proxy nke ndị ọgbọ abụọ ahụ na-ahụ anya. Ọ na-agbakwụnye latency ma dị oke ọnụ iji mejuputa karịa STUN (n'ihi na a na-etinye ya n'ọrụ n'ime oge nkwurịta okwu dum), ma mgbe ụfọdụ ọ bụ naanị nhọrọ.
  • Ntọala Njikọta mmekọrịta (ice) a na-eji họrọ usoro kachasị mma iji jikọọ ndị ọgbọ abụọ dabere na ozi enwetara site na ijikọta ndị ọgbọ ozugbo, yana ozi natara site na ọnụọgụ ọ bụla nke STUN na TURN sava.
  • Protocol nkọwa nke oge (RDS) bụ usoro maka ịkọwapụta paramita ọwa njikọ, dịka ọmụmaatụ, ndị na-aga ICE, codecs multimedia (n'ihe gbasara ọwa ọdịyo / vidiyo), wdg ... Otu n'ime ndị ọgbọ na-eziga onyinye SDP, nke abụọ na-aza azịza SDP. . Mgbe nke a gasịrị, a na-emepụta ọwa.

Iji mepụta njikọ dị otú ahụ, ndị ọgbọ kwesịrị ịnakọta ozi ha nwetara site na sava STUN na TURN wee gbanwee ya na ibe ha.

Nsogbu bụ na ha enwebeghị ike ịkparịta ụka ozugbo, yabụ usoro nke na-apụ apụ ga-adịrịrị iji gbanwee data a: ihe nkesa na-egosi.

Ihe nkesa na-egosi nwere ike ịdị mfe n'ihi na naanị ọrụ ya bụ ibugharị data n'etiti ndị ọgbọ n'oge mmekọ aka (dị ka egosiri na eserese dị n'okpuru).

Jiri Cheerp, WebRTC na Firebase na-ebufe egwuregwu ọtụtụ mmadụ site na C++ gaa na webụ
Eserese usoro mmekwa aka WebRTC dị mfe

Nlebanya Model Network Teeworlds

Nhazi netwọk Teeworlds dị nnọọ mfe:

  • Ihe ndị ahịa na ihe nkesa bụ mmemme abụọ dị iche iche.
  • Ndị ahịa na-abanye egwuregwu ahụ site na ijikọ na otu n'ime ọtụtụ sava, nke ọ bụla na-akwado naanị otu egwuregwu n'otu oge.
  • A na-eme mbufe data niile na egwuregwu ahụ site na ihe nkesa.
  • A na-eji ihe nkesa nna ukwu pụrụ iche na-anakọta ndepụta nke sava ọha niile nke egosiri na onye ahịa egwuregwu.

Ekele maka iji WebRTC maka mgbanwe data, anyị nwere ike ịnyefe ihe nkesa nke egwuregwu ahụ na ihe nchọgharị ebe onye ahịa dị. Nke a na-enye anyị nnukwu ohere...

Wepụ sava

Enweghị mgbagha ihe nkesa nwere ọmarịcha uru: anyị nwere ike ibuga ngwa ahụ niile dị ka ọdịnaya kwụ ọtọ na ibe Github ma ọ bụ na ngwaike nke anyị n'azụ Cloudflare, si otú a na-eme ka nbudata ngwa ngwa na oge dị elu n'efu. N'ezie, anyị nwere ike ichefu banyere ha, ma ọ bụrụ na anyị nwere chi ọma na egwuregwu ahụ na-ewu ewu, mgbe ahụ, akụrụngwa agaghị eme ka ọ dị ọhụrụ.

Agbanyeghị, maka sistemụ ahụ ka ọ rụọ ọrụ, anyị ka ga-eji ihe owuwu mpụga:

  • Otu sava STUN ma ọ bụ karịa: Anyị nwere ọtụtụ nhọrọ efu ịhọrọ site na.
  • Opekempe otu ihe nkesa atụgharị: enweghị nhọrọ efu ebe a, yabụ anyị nwere ike hazie nke anyị ma ọ bụ kwụọ ụgwọ maka ọrụ ahụ. Ọ dabara nke ọma, ọtụtụ oge enwere ike ịmepụta njikọ site na sava STUN (ma nye ezi p2p), mana TURN dị mkpa dị ka nhọrọ ọdịda.
  • Ihe nkesa na-egosi akara: N'adịghị ka akụkụ abụọ ndị ọzọ, ahazighị akara ngosi. Ihe nkesa na-egosi n'ezie ga-abụ maka ya dabere ntakịrị na ngwa ahụ. N'ọnọdụ anyị, tupu ịmepụta njikọ, ọ dị mkpa ịgbanwe ntakịrị data.
  • Teeworlds Master Server: Ndị sava ndị ọzọ na-eji ya kpọsaa ịdị adị ha yana ndị ahịa iji chọta sava ọha. Ọ bụ ezie na ọ dịghị achọ (ndị ahịa nwere ike jikọọ na ihe nkesa ha na-eji aka), ọ ga-adị mma ịnwe ka ndị egwuregwu wee soro ndị mmadụ na-egwu egwuregwu.

Anyị kpebiri iji sava STUN efu nke Google, wee bufee otu sava TURN n'onwe anyị.

Maka isi ihe abụọ ikpeazụ anyị ji mee ihe Firebase:

  • A na-emejuputa ihe nkesa Master Teeworlds n'ụzọ dị mfe: dịka ndepụta nke ihe nwere ozi (aha, IP, map, mode, ...) nke ihe nkesa ọ bụla na-arụ ọrụ. Sava na-ebipụta ma na-emelite ihe nke ha, ndị ahịa na-ewere ndepụta ahụ dum wee gosipụta ya na onye ọkpụkpọ. Anyị na-egosipụtakwa ndepụta dị na ibe mbụ dị ka HTML ka ndị egwuregwu nwee ike pịa ihe nkesa ahụ wee buru ya ozugbo na egwuregwu ahụ.
  • Ịrịba ama nwere njikọ chiri anya na mmejuputa sọket anyị, akọwapụtara na ngalaba na-esote.

Jiri Cheerp, WebRTC na Firebase na-ebufe egwuregwu ọtụtụ mmadụ site na C++ gaa na webụ
Ndepụta nke sava dị n'ime egwuregwu yana na ibe mbụ

Mmejuputa oghere

Anyị chọrọ ịmepụta API nke dị nso na Posix UDP Sockets dị ka o kwere mee iji belata ọnụọgụ mgbanwe achọrọ.

Anyị chọkwara imejuputa opekempe dị mkpa maka mgbanwe data kachasị mfe na netwọkụ.

Dịka ọmụmaatụ, anyị achọghị ezigbo ụzọ ụgbọ ala: ndị ọgbọ niile nọ n'otu "LAN mebere" jikọtara ya na ihe atụ nchekwa data Firebase.

Ya mere, anyị achọghị adreesị IP pụrụ iche: ụkpụrụ igodo Firebase pụrụ iche (dị ka aha ngalaba) zuru ezu iji mata ndị ọgbọ n'ụzọ pụrụ iche, ndị ọgbọ ọ bụla na-ekenye adreesị IP "adịgboroja" na igodo ọ bụla kwesịrị ịtụgharị. Nke a na-ewepụ kpamkpam mkpa maka ọrụ adreesị IP zuru ụwa ọnụ, nke bụ ọrụ na-adịghị mkpa.

Nke a bụ API kacha nta anyị kwesịrị ime:

// 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 dị mfe ma yie Posix Sockets API, mana nwere ọdịiche dị mkpa ole na ole: ịdekọ oku azụ, na-ekenye IP mpaghara, yana njikọ ndị umengwụ.

Ịdenye ahaghachi oku

Ọbụlagodi na mmemme izizi na-eji I/O anaghị egbochi, koodu ahụ ga-emerịrị ka ọ na-agba ọsọ na ihe nchọgharị weebụ.

Ihe kpatara nke a bụ na ezoro ezo loop omume na ihe nchọgharị site na mmemme (ma ọ bụrụ Javascript ma ọ bụ WebAssembly).

Na gburugburu obodo anyị nwere ike ide koodu dịka nke a

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

Ọ bụrụ na ezoro ezo loop mmemme ahụ, yabụ anyị kwesịrị ịtụgharị ya ka ọ bụrụ nke a:

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

Ọrụ IP mpaghara

NJ ọnụ na "netwọk" anyị abụghị adreesị IP, kama igodo Firebase (ha bụ eriri dị ka nke a: -LmEC50PYZLCiCP-vqde ).

Nke a dị mma n'ihi na anyị achọghị usoro maka ikenye IP na ịlele ọdịiche ha (yana tụfuo ha mgbe onye ahịa kwụsịrị), mana ọ na-adịkarị mkpa iji ọnụọgụ ọnụọgụ chọpụta ndị ọgbọ.

Nke a bụ kpọmkwem ihe a na-eji arụ ọrụ. resolve и reverseResolve: Ngwa n'ụzọ ụfọdụ na-enweta uru eriri igodo (site na ntinye onye ọrụ ma ọ bụ site na sava ukwu), ma nwee ike ịtụgharị ya na adreesị IP maka ojiji nke ime. API ndị ọzọ na-enwetakwa uru a kama eriri maka ịdị mfe.

Nke a yiri nyocha DNS, mana emere ya na mpaghara na onye ahịa.

Ya bụ, enweghị ike ịkekọrịta adreesị IP n'etiti ndị ahịa dị iche iche, ma ọ bụrụ na achọrọ ụdị njirimara zuru ụwa ọnụ, a ga-emepụta ya n'ụzọ dị iche.

Njikọ ume ume

UDP achọghị njikọ, mana dị ka anyị hụworo, WebRTC chọrọ usoro njikọ ogologo tupu ọ malite ịnyefe data n'etiti ndị ọgbọ abụọ.

Ọ bụrụ na anyị chọrọ ịnye otu ọkwa nke abstraction, (sendto/recvfrom ya na ndị ọgbọ aka ike na-enweghị njikọ mbụ), mgbe ahụ, ha ga-eme njikọ "ume ume" (egbu oge) n'ime API.

Nke a bụ ihe na-eme n'oge mkparịta ụka nkịtị n'etiti "ihe nkesa" na "onye ahịa" mgbe ị na-eji UDP, yana ihe ọbá akwụkwọ anyị kwesịrị ime:

  • Oku sava bind()ịgwa sistemụ arụmọrụ na ọ chọrọ ịnata ngwugwu na ọdụ ụgbọ mmiri akọwapụtara.

Kama, anyị ga-ebipụta ọdụ ụgbọ mmiri mepere emepe na Firebase n'okpuru igodo sava wee gee ihe omume n'ime obere osisi ya.

  • Oku sava recvfrom(), ịnakwere ngwugwu na-abịa site na onye ọ bụla ọbịa na ọdụ ụgbọ mmiri a.

N'ọnọdụ anyị, anyị kwesịrị ịlele ahịrị na-abata nke ngwugwu ezigara n'ọdụ ụgbọ mmiri a.

Ọdụ ụgbọ mmiri ọ bụla nwere kwụ n'ahịrị nke ya, anyị na-agbakwunye isi iyi na ọdụ ụgbọ mmiri na-aga na mmalite nke datagram WebRTC ka anyị mara nke kwụ n'ahịrị anyị ga-ebuga mgbe ngwugwu ọhụrụ rutere.

Oku a naghị egbochi ya, yabụ ọ bụrụ na enweghị ngwugwu, anyị ga-alaghachi -1 wee tọọ ya errno=EWOULDBLOCK.

  • Onye ahịa na-enweta IP na ọdụ ụgbọ mmiri nke ihe nkesa site na ụfọdụ ụzọ mpụga, na oku sendto(). Nke a na-emekwa oku ime. bind(), yabụ na-esote recvfrom() ga-enweta nzaghachi na-enweghị n'ụzọ doro anya na-eme nkekọ.

N'ọnọdụ anyị, onye ahịa na-enweta igodo eriri na mpụga ma jiri ọrụ ahụ resolve() iji nweta adreesị IP.

N'oge a, anyị na-amalite aka WebRTC ma ọ bụrụ na ndị ọgbọ abụọ ahụ ejikọtabeghị onwe ha. Njikọ na ọdụ ụgbọ mmiri dị iche iche nke otu ọgbọ na-eji otu WebRTC DataChannel.

Anyị na-eme ihe na-apụtaghị ìhè bind()ka ihe nkesa wee nwee ike jikọọ ọzọ na-esote sendto() ọ bụrụ na o mechiri n'ihi ihe ụfọdụ.

A na-eme ka ihe nkesa ahụ mara maka njikọ onye ahịa mgbe onye ahịa dere onyinye SDP ya n'okpuru ozi ọdụ ụgbọ mmiri dị na Firebase, ihe nkesa na-azaghachi na nzaghachi ya n'ebe ahụ.

Eserese dị n'okpuru na-egosi ihe atụ nke mgbaba ozi maka atụmatụ oghere yana nnyefe ozi mbụ sitere n'aka onye ahịa gaa na nkesa:

Jiri Cheerp, WebRTC na Firebase na-ebufe egwuregwu ọtụtụ mmadụ site na C++ gaa na webụ
Eserese zuru oke nke usoro njikọ n'etiti onye ahịa na nkesa

nkwubi

Ọ bụrụ na ị gụọla nke a, ọ ga-abụrịrị na ị ga-enwe mmasị ịhụ na tiori na-arụ ọrụ. Enwere ike ịme egwuregwu ahụ teeworlds.leaningtech.com, nwaa ya!


Egwuregwu enyi na enyi n'etiti ndị ọrụ ibe

Koodu ọba akwụkwọ netwọk dị n'efu na Github. Soro mkparịta ụka na ọwa anyị na Gitter!

isi: www.habr.com

Tinye a comment