Gbigbe ere elere pupọ lati C ++ si oju opo wẹẹbu pẹlu Cheerp, WebRTC ati Firebase

Ifihan

ile-iṣẹ wa Awọn imọ-ẹrọ gbigbe pese awọn solusan fun gbigbe awọn ohun elo tabili tabili ibile si oju opo wẹẹbu. Akopọ C ++ wa idunnu n ṣe akojọpọ ti WebAssembly ati JavaScript, eyiti o pese mejeeji o rọrun browser ibaraenisepo, ati ki o ga išẹ.

Gẹgẹbi apẹẹrẹ ti ohun elo rẹ, a pinnu lati gbe ere elere pupọ si oju opo wẹẹbu ati yan Teeworlds. Teeworlds jẹ ere retro 2D pupọ pupọ pẹlu agbegbe kekere ṣugbọn ti nṣiṣe lọwọ ti awọn oṣere (pẹlu mi!). O jẹ kekere mejeeji ni awọn ofin ti awọn orisun ti a ṣe igbasilẹ ati Sipiyu ati awọn ibeere GPU - oludije pipe.

Gbigbe ere elere pupọ lati C ++ si oju opo wẹẹbu pẹlu Cheerp, WebRTC ati Firebase
Nṣiṣẹ ni ẹrọ aṣawakiri Teeworlds

A pinnu lati lo iṣẹ akanṣe yii lati ṣe idanwo pẹlu awọn solusan gbogbogbo fun gbigbe koodu nẹtiwọki si oju opo wẹẹbu. Eyi ni a ṣe nigbagbogbo ni awọn ọna wọnyi:

  • Ibeere XMLHttp/fa, ti apakan nẹtiwọki ba ni awọn ibeere HTTP nikan, tabi
  • ayelujara iho.

Awọn solusan mejeeji nilo gbigbalejo paati olupin ni ẹgbẹ olupin, ati pe ko gba laaye fun lilo bi ilana gbigbe UDP. Eyi ṣe pataki fun awọn ohun elo akoko gidi gẹgẹbi sọfitiwia apejọ fidio ati awọn ere, nitori pe o ṣe iṣeduro ifijiṣẹ ati aṣẹ ti awọn idii ilana. TCP le di idiwo si kekere lairi.

Ọna kẹta wa - lo nẹtiwọọki lati ẹrọ aṣawakiri: WebRTC.

RTCDataChannel O ṣe atilẹyin mejeeji igbẹkẹle ati gbigbe gbigbe ti ko ni igbẹkẹle (ninu ọran igbeyin o gbiyanju lati lo UDP bi ilana gbigbe ni gbogbo igba ti o ṣeeṣe), ati pe o le ṣee lo mejeeji pẹlu olupin latọna jijin ati laarin awọn aṣawakiri. Eyi tumọ si pe a le gbe gbogbo ohun elo sori ẹrọ aṣawakiri, pẹlu paati olupin!

Sibẹsibẹ, eyi wa pẹlu iṣoro afikun: ṣaaju ki awọn ẹlẹgbẹ WebRTC meji le ṣe ibaraẹnisọrọ, wọn nilo lati ṣe imudani ti o ni idiwọn lati sopọ, eyiti o nilo ọpọlọpọ awọn ohun elo ẹni-kẹta (olupin ifihan agbara ati ọkan tabi diẹ sii olupin). STUN/TAN).

Bi o ṣe yẹ, a fẹ lati ṣẹda API nẹtiwọki kan ti o nlo WebRTC ni inu, ṣugbọn o sunmọ bi o ti ṣee ṣe si wiwo UDP Sockets ti ko nilo lati fi idi asopọ kan mulẹ.

Eyi yoo gba wa laaye lati lo anfani WebRTC laisi nini lati ṣafihan awọn alaye eka si koodu ohun elo (eyiti a fẹ lati yipada bi diẹ bi o ti ṣee ninu iṣẹ akanṣe wa).

Iye ti o ga julọ ti WebRTC

WebRTC jẹ eto API ti o wa ninu awọn aṣawakiri ti o pese gbigbejade ẹlẹgbẹ-si-ẹlẹgbẹ ti ohun, fidio ati data lainidii.

Isopọ laarin awọn ẹlẹgbẹ ti wa ni idasilẹ (paapaa ti NAT ba wa ni ọkan tabi awọn ẹgbẹ mejeeji) lilo STUN ati / tabi awọn olupin TURN nipasẹ ọna ti a npe ni ICE. Awọn ẹlẹgbẹ ṣe paṣipaarọ alaye ICE ati awọn aye ikanni nipasẹ ipese ati idahun ti ilana SDP.

Iro ohun! Awọn kuru melo melo ni akoko kan? Jẹ ki a ṣe alaye ni ṣoki kini awọn ofin wọnyi tumọ si:

  • Ikoni Traversal Utilities fun NAT (STUN) - Ilana fun lilọ kiri NAT ati gbigba bata (IP, ibudo) fun paṣipaarọ data taara pẹlu agbalejo naa. Ti o ba ṣakoso lati pari iṣẹ-ṣiṣe rẹ, lẹhinna awọn ẹlẹgbẹ le ṣe paṣipaarọ data ni ominira pẹlu ara wọn.
  • Traversal Lilo Relays ni ayika NAT (TAN) tun lo fun lilọ kiri NAT, ṣugbọn o ṣe eyi nipa gbigbe data siwaju nipasẹ aṣoju ti o han si awọn ẹlẹgbẹ mejeeji. O ṣe afikun lairi ati pe o jẹ gbowolori diẹ sii lati ṣe ju STUN (nitori pe o lo jakejado gbogbo igba ibaraẹnisọrọ), ṣugbọn nigbami o jẹ aṣayan nikan.
  • Ibanisọrọ Asopọmọra idasile (yinyin) ti a lo lati yan ọna ti o dara julọ ti sisopọ awọn ẹlẹgbẹ meji ti o da lori alaye ti a gba lati awọn ẹlẹgbẹ sisopọ taara, bakannaa alaye ti o gba nipasẹ eyikeyi nọmba ti STUN ati awọn olupin TURN.
  • Ilana Apejuwe Ikoni (RDS) jẹ ọna kika fun apejuwe awọn paramita ikanni asopọ, fun apẹẹrẹ, awọn oludije ICE, awọn codecs multimedia (ninu ọran ti ikanni ohun ohun/fidio), bbl . Lẹhin eyi, a ṣẹda ikanni kan.

Lati ṣẹda iru asopọ bẹ, awọn ẹlẹgbẹ nilo lati gba alaye ti wọn gba lati ọdọ awọn olupin STUN ati TURN ati paarọ rẹ pẹlu ara wọn.

Iṣoro naa ni pe wọn ko sibẹsibẹ ni agbara lati baraẹnisọrọ taara, nitorinaa ẹrọ ti ita-band gbọdọ wa lati paarọ data yii: olupin ifihan.

Olupin ifihan le rọrun pupọ nitori pe iṣẹ rẹ nikan ni lati firanṣẹ data laarin awọn ẹlẹgbẹ ni ipele imufọwọwọ (gẹgẹ bi o ṣe han ninu aworan atọka isalẹ).

Gbigbe ere elere pupọ lati C ++ si oju opo wẹẹbu pẹlu Cheerp, WebRTC ati Firebase
Irọrun WebRTC atọwọdọwọ ọkọọkan

Teeworlds Network awoṣe Akopọ

faaji nẹtiwọki Teeworlds rọrun pupọ:

  • Onibara ati awọn paati olupin jẹ awọn eto oriṣiriṣi meji.
  • Awọn alabara tẹ ere sii nipa sisopọ si ọkan ninu awọn olupin pupọ, ọkọọkan eyiti o gbalejo ere kan ṣoṣo ni akoko kan.
  • Gbogbo gbigbe data ninu ere naa ni a ṣe nipasẹ olupin naa.
  • A pataki olupin titunto si ti wa ni lo lati gba akojọ kan ti gbogbo awọn àkọsílẹ olupin ti o ti wa ni han ni awọn ere ni ose.

Ṣeun si lilo WebRTC fun paṣipaarọ data, a le gbe paati olupin ti ere naa si ẹrọ aṣawakiri nibiti alabara wa. Eyi fun wa ni anfani nla ...

Yọ awọn olupin kuro

Aini oye olupin ni anfani to wuyi: a le mu gbogbo ohun elo naa ṣiṣẹ bi akoonu aimi lori Awọn oju-iwe Github tabi lori ohun elo tiwa lẹhin Cloudflare, nitorinaa ni idaniloju awọn igbasilẹ iyara ati akoko giga fun ọfẹ. Looto, a le gbagbe nipa won, ti a ba si ni orire ti ere naa si di olokiki, lẹhinna awọn amayederun ko ni lati di olaju.

Sibẹsibẹ, fun eto lati ṣiṣẹ, a tun ni lati lo faaji ita:

  • Ọkan tabi diẹ ẹ sii olupin STUN: A ni ọpọlọpọ awọn aṣayan ọfẹ lati yan lati.
  • O kere ju olupin TAN: ko si awọn aṣayan ọfẹ nibi, nitorinaa a le ṣeto tiwa tabi sanwo fun iṣẹ naa. O da, pupọ julọ akoko asopọ naa le ti fi idi mulẹ nipasẹ awọn olupin STUN (ati pese p2p otitọ), ṣugbọn TURN ni a nilo bi aṣayan isubu.
  • Olupin ifihan agbara: Ko dabi awọn aaye meji miiran, ifihan ifihan ko ni idiwọn. Ohun ti olupin ifihan yoo jẹ iduro fun gangan da lori ohun elo naa. Ninu ọran wa, ṣaaju iṣeto asopọ, o jẹ dandan lati paarọ iye kekere ti data.
  • Teeworlds Titunto Server: O jẹ lilo nipasẹ awọn olupin miiran lati polowo aye wọn ati nipasẹ awọn alabara lati wa awọn olupin gbangba. Lakoko ti o ko nilo (awọn alabara le sopọ nigbagbogbo si olupin ti wọn mọ nipa ọwọ), yoo dara lati ni ki awọn oṣere le kopa ninu awọn ere pẹlu eniyan laileto.

A pinnu lati lo awọn olupin STUN ọfẹ ti Google, a si gbe olupin TURN kan funrara wa.

Fun awọn ti o kẹhin meji ojuami ti a lo Firebase:

  • Olupin titunto si Teeworlds jẹ imuse ni irọrun pupọ: gẹgẹbi atokọ ti awọn nkan ti o ni alaye (orukọ, IP, maapu, ipo, ...) ti olupin ti nṣiṣe lọwọ kọọkan. Awọn olupin ṣe atẹjade ati ṣe imudojuiwọn nkan tiwọn, ati awọn alabara mu gbogbo atokọ naa ki o ṣafihan si ẹrọ orin. A tun han awọn akojọ lori ile-iwe bi HTML ki awọn ẹrọ orin le nìkan tẹ lori olupin ati ki o wa ni ya taara si awọn ere.
  • Iforukọsilẹ jẹ ibatan pẹkipẹki si imuse awọn sockets wa, ti a ṣalaye ni apakan atẹle.

Gbigbe ere elere pupọ lati C ++ si oju opo wẹẹbu pẹlu Cheerp, WebRTC ati Firebase
Akojọ awọn olupin inu ere ati lori oju-iwe ile

Imuse ti sockets

A fẹ ṣẹda API kan ti o sunmọ Posix UDP Sockets bi o ti ṣee ṣe lati dinku nọmba awọn ayipada ti o nilo.

A tun fẹ lati ṣe iwulo o kere ju ti o nilo fun paṣipaarọ data ti o rọrun julọ lori nẹtiwọọki.

Fun apẹẹrẹ, a ko nilo ipa-ọna gidi: gbogbo awọn ẹlẹgbẹ wa lori “LAN foju” kanna ti o ni nkan ṣe pẹlu apẹẹrẹ aaye data Firebase kan pato.

Nitorinaa, a ko nilo awọn adirẹsi IP alailẹgbẹ: awọn iye bọtini pataki Firebase (iru si awọn orukọ ìkápá) ti to lati ṣe idanimọ awọn ẹlẹgbẹ alailẹgbẹ, ati pe ẹlẹgbẹ kọọkan ni agbegbe n yan awọn adirẹsi IP “iro” si bọtini kọọkan ti o nilo lati tumọ. Eyi yọkuro iwulo fun iṣẹ iyansilẹ adiresi IP agbaye, eyiti o jẹ iṣẹ-ṣiṣe ti kii ṣe pataki.

Eyi ni API ti o kere julọ ti a nilo lati ṣe:

// 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 rọrun ati iru si Posix Sockets API, ṣugbọn o ni awọn iyatọ pataki diẹ: wíwọlé callbacks, sọtọ IPs agbegbe, ati ọlẹ awọn isopọ.

Iforukọsilẹ Callbacks

Paapa ti eto atilẹba ba nlo I/O ti kii ṣe idinamọ, koodu naa gbọdọ jẹ atunṣe lati ṣiṣẹ ni ẹrọ aṣawakiri wẹẹbu kan.

Idi fun eyi ni pe iṣẹlẹ iṣẹlẹ ni ẹrọ aṣawakiri ti wa ni pamọ lati inu eto naa (jẹ JavaScript tabi WebAssembly).

Ni agbegbe abinibi a le kọ koodu bii eyi

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

Ti lupu iṣẹlẹ ba farapamọ si wa, lẹhinna a nilo lati yi pada si nkan bii eyi:

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

Ipinfunni IP agbegbe

Awọn ID node ti o wa ninu “nẹtiwọọki” wa kii ṣe awọn adirẹsi IP, ṣugbọn awọn bọtini Firebase (wọn jẹ awọn okun ti o dabi eyi: -LmEC50PYZLCiCP-vqde ).

Eyi rọrun nitori a ko nilo ẹrọ kan fun yiyan IPs ati ṣayẹwo iyasọtọ wọn (bakanna bi sisọnu wọn lẹhin awọn asopọ ti alabara), ṣugbọn o jẹ pataki nigbagbogbo lati ṣe idanimọ awọn ẹlẹgbẹ nipasẹ iye nọmba kan.

Eleyi jẹ gangan ohun ti awọn iṣẹ ti wa ni lilo fun. resolve и reverseResolve: Ohun elo bakan gba iye okun ti bọtini (nipasẹ titẹ sii olumulo tabi nipasẹ olupin oluwa), ati pe o le yi pada si adiresi IP fun lilo inu. Awọn iyokù API tun gba iye yii dipo okun fun ayedero.

Eyi jẹ iru si wiwa DNS, ṣugbọn o ṣe ni agbegbe lori alabara.

Iyẹn ni, awọn adirẹsi IP ko le ṣe pinpin laarin awọn alabara oriṣiriṣi, ati pe ti iru idanimọ agbaye ba nilo, yoo ni lati ṣe ipilẹṣẹ ni ọna ti o yatọ.

Asopọ ọlẹ

UDP ko nilo asopọ kan, ṣugbọn bi a ti rii, WebRTC nilo ilana asopọ gigun ṣaaju ki o le bẹrẹ gbigbe data laarin awọn ẹlẹgbẹ meji.

Ti a ba fẹ pese ipele kanna ti abstraction, (sendto/recvfrom pẹlu awọn ẹlẹgbẹ lainidii laisi asopọ iṣaaju), lẹhinna wọn gbọdọ ṣe asopọ “ọlẹ” (idaduro) inu API.

Eyi ni ohun ti o ṣẹlẹ lakoko ibaraẹnisọrọ deede laarin “olupin” ati “alabara” nigba lilo UDP, ati kini ile-ikawe wa yẹ ki o ṣe:

  • Awọn ipe olupin bind()lati sọ fun ẹrọ ṣiṣe pe o fẹ lati gba awọn apo-iwe lori ibudo ti a sọ.

Dipo, a yoo ṣe atẹjade ibudo ṣiṣi si Firebase labẹ bọtini olupin ati tẹtisi awọn iṣẹlẹ ni abẹlẹ rẹ.

  • Awọn ipe olupin recvfrom(), gbigba awọn apo-iwe ti o nbọ lati ọdọ ogun eyikeyi lori ibudo yii.

Ninu ọran wa, a nilo lati ṣayẹwo isinyi ti nwọle ti awọn apo-iwe ti a firanṣẹ si ibudo yii.

Ibudo kọọkan ni isinyi tirẹ, ati pe a ṣafikun orisun ati awọn ebute oko oju-irin si ibẹrẹ ti awọn datagram WebRTC ki a le mọ iru isinyi lati firanṣẹ siwaju si nigbati soso tuntun ba de.

Ipe naa kii ṣe idilọwọ, nitorina ti ko ba si awọn apo-iwe, a kan pada -1 ati ṣeto errno=EWOULDBLOCK.

  • Onibara gba IP ati ibudo olupin nipasẹ diẹ ninu awọn ọna ita, ati awọn ipe sendto(). Eyi tun ṣe ipe inu. bind(), nitorina atẹle recvfrom() yoo gba esi lai ṣe kedere pipaṣẹ dè.

Ninu ọran wa, alabara ni ita gba bọtini okun ati lo iṣẹ naa resolve() lati gba adiresi IP kan.

Ni aaye yii, a bẹrẹ ifọwọyi WebRTC ti awọn ẹlẹgbẹ meji ko ba ti sopọ mọ ara wọn. Awọn asopọ si oriṣiriṣi awọn ebute oko oju omi ti ẹlẹgbẹ kanna lo WebRTC DataChannel kanna.

A tun ṣe aiṣe-taara bind()ki olupin le tun sopọ ni atẹle sendto() ni irú ti o ni pipade fun diẹ ninu awọn idi.

Awọn olupin ti wa ni iwifunni ti awọn ose ká asopọ nigbati awọn ose kọ awọn oniwe-SDP ìfilọ labẹ awọn olupin ibudo alaye ni Firebase, ati awọn olupin idahun pẹlu awọn oniwe-esi nibẹ.

Aworan ti o wa ni isalẹ fihan apẹẹrẹ ti sisan ifiranṣẹ fun ero iho ati gbigbe ifiranṣẹ akọkọ lati ọdọ alabara si olupin naa:

Gbigbe ere elere pupọ lati C ++ si oju opo wẹẹbu pẹlu Cheerp, WebRTC ati Firebase
Aworan pipe ti ipele asopọ laarin alabara ati olupin

ipari

Ti o ba ti ka eyi jina, o ṣee ṣe ki o nifẹ lati rii imọran ni iṣe. Awọn ere le wa ni dun lori teeworlds.leaningtech.com, danwo!


Baramu ore laarin awọn ẹlẹgbẹ

Koodu ikawe nẹtiwọki wa larọwọto ni Github. Darapọ mọ ibaraẹnisọrọ lori ikanni wa ni Gitter!

orisun: www.habr.com

Fi ọrọìwòye kun