Ludum lusorium ex C ++ portans ad telam cum Cheerp, WebRTC et Firebase

introduction

societas nostra Technologies innixus solutiones praebet pro escritorio traditionalis applicationes ad textum portandum. Nostrum C++ compilator cheerp WebAssembly et JavaScript, coniunctio generat, quae utrumque praebet simplex pasco commerciumac magna.

Exemplum applicationis eius pluribus lusoribus ludum interreti ac delegi placuit Teeworlds. Teeworlds lusoribus 2D retro lusoribus est cum parva sed activa communitas lusorum (me inclusa!). Parva est tam secundum facultates receptas et CPU ac GPU requisita - candidatus optimus.

Ludum lusorium ex C ++ portans ad telam cum Cheerp, WebRTC et Firebase
Currens in pasco Teeworlds

Placuimus ut hoc project ad experimentum solutiones generales pro traiciendi network codice ad telam. Id autem his modis fieri solet;

  • XMLHttpRequest/arce, si pars retis consistit in petitionibus HTTP , vel
  • WebSockets.

Utraeque solutiones exigunt partem ministrantis in parte ministrantis obnoxiam, et neutra admittit usum protocollo in modum onerariae UDP. Hoc magni momenti est ad applicationes reales temporis sicut in programmatibus et ludis conferendis ut video, quia traditio et ordo protocolli facis TCP fiat impedimentum humilitatis latency.

Tertius modus est - utere retis ex navigatro: WebRTC.

RTCDataChannel Sustentat tam certam quam incertam transmissionem (in hoc casu UDP protocollo onerario quoties fieri potest) uti conatur et tum cum remoto servo tum inter navigatores adhiberi potest. Hoc significat nos totam applicationem ad navigatrum, incluso componente servo, portare possumus!

Sed hoc cum difficultate addito venit: antequam duo pares WebRTC communicare possunt, opus habent maculosum complexum relativum ad coniungere, quae plures res tertiae factionis requirit (signans cultor et unus vel plures servientes. STUN/CIRCUITUS).

Specimen, velis creare retis API, qui WebRTC interne utitur, sed quam proxime potest ad bases interfaciei UDP quae nexum constituere non oportet.

Hoc nobis permittet uti WebRTC non habens singula implicata exponere in codice schedula (quam quam minimum mutare voluimus in consilio nostro).

Minimum WebRTC

WebRTC copia APIs in navigatoribus est quae praebet transmissionem paris-parem auditionis, video datae et arbitrariae.

Connexio inter pares constituitur (etsi in una vel utraque parte NAT) utens STUN et/vel ORDINEM ministrantium per mechanismum ICE vocatum. pares informationes glaciei permutant et parametri canalis per oblationes et responsionem protocolli SDP commutant.

proh! Quot abbreviations in uno tempore? Quid sibi velint haec verba breviter exponamus:

  • Sessio Traversal Utilitas ad NAT (STUN) — protocollum ad praetereundo NAT et obtinendum par (IP, port) ad notitias directe commutandas cum exercitu. Si negotium suum perficiendum procurat, tunc pares sine notitia inter se permutare possunt.
  • Traversal Using CURSUS circa NAT (CIRCUITUS) adhibetur etiam pro NAT traversal, sed hoc efficit ut notitias transmittentes per procuratorem utriusque paris conspicuum. Latentiam addit et carior est efficiendi quam STUN (quia adhibetur per totam sessionem communicationis), sed interdum sola est optio.
  • Interactive Connectivity De instauratione (REFRIGERO) usus est eligere optimam methodum connectendi duos pares innixos in informationibus e connectendis se directis habitis, ac informationes receptas ab aliquo numero STUN et ORDINE ministrantium.
  • Sessio Description Protocollum (RDS) forma est ad describendum nexum canalis parametri, exempli gratia, candidati ICE, multimedia codeci (si canalis audio/video) etc. ... Una parrum mittit Offertorium SDP, et secunda respondet cum Responsio SDP . Postea canalis creatur.

Ad talem nexum efficiendam, pares informationes colligendas, quas ab STUN et ORDINE servientibus accipiunt, necesse est ut inter se commutent.

Problema est quod nondum facultatem directe communicandi habent, sic mechanismus extra bandam hanc datam commutare debet: significans server.

Servus significans valde simplex esse potest quod unicum eius officium est ut notitias inter pares in periodo handshake exhibeat (ut infra in schemate ostenditur).

Ludum lusorium ex C ++ portans ad telam cum Cheerp, WebRTC et Firebase
Simplicior WebRTC handshake sequence diagram

Teeworlds Network Model Overview

Teeworlds retis architectura valde simplex est:

  • Cliens et server components duo diversa programmata sunt.
  • Clientes ludum intrant coniungendo uni ex pluribus servientibus, quorum singuli exercitus unum tantum ludum ad tempus habent.
  • Omnis notitia translationis in ludo exercetur per servo.
  • Peculiaris dominus servo adhibetur ad colligendam summam omnium publicorum ministrorum, qui in ludo clientis exhibentur.

Propter usum WebRTC pro notitia commutationis, partem ludi ministratoris transferre possumus ad navigatorem ubi hic sita est. Magnam hic occasionem nobis dat...

Ejice servers

Defectus serveris logicae pulchrum commodum habet: totam applicationem ut statice in Paginae Github vel in propriis ferramentis post Cloudflare explicari possumus, ita ut celeriter downloads et alte uptime gratis exponamus. Re quidem vera de illis oblivisci possumus, et si sumus felix et ludus popularis fit, infrastructura modernised non erit.

Sed, ad rationem laboris, architectura externa uti adhuc habemus;

  • Unus vel plures STUN servientes: plures optiones liberas habemus ex eligendo.
  • Saltem unus servo VICARIUS: nullae optiones hic liberae sunt, ut vel nostram constituere possumus vel pro servitio reddere. Fortunate, temporis coniunctio, per STUN servers (et verum p2p praebere potest), sed ORDINE opus est ut optio fallacum.
  • Significans Servo: Dissimilis duobus aliis aspectibus, significatio non est normatum. Id quod significans server actu responsabilis erit pro aliquo applicatione dependet. In nobis, antequam nexum constituat, parva notitia permutare oportet.
  • Magister Servus Teeworlds: ab aliis servientibus praedicat suam existentiam et ab clientibus in servis publicis invenitur. Dum suus non requiritur (clientes semper coniungere possunt servo quod sciunt de manually), esset nice habere ut histriones ludos cum hominibus incertis participare possint.

Nos placuit servientibus Googles liberis STUN uti, et unum ORDINEM servo ipsi explicavimus.

Ad duo ultima puncta nos utebamur Firebase:

  • Dominus servitor Teeworlds simpliciter impletur: ut index rerum quae notitiarum (nomen, IP, tabula, modus, ...) cuiusque activum ministratur. Servi divulgant et suum obiectum renovant, et clientes totum album capiunt et illud scaenicis ostendunt. Indicem etiam in pagina domestica sicut HTML exhibemus, ita lusores simpliciter deprime in calculonis et ad ludum recte deponi possunt.
  • Significatio propinqua est exsecutioni basibus nostris, de quibus in sequenti articulo.

Ludum lusorium ex C ++ portans ad telam cum Cheerp, WebRTC et Firebase
Index servorum intra ludum et in pagina prima

Exsequendam bases

Facere API volumus quod tam prope Posixum UDP Sockets quam maxime ad minuendum numerum mutationum quae fieri possunt.

Etiam necessariam minimum efficere volumus pro notitia simplicissima commutationis super retiacula requisita.

Exempli gratia, realem fusuram non indigemus: omnes pares idem "LAN virtual" coniunguntur cum instantia specifica database Firebase.

Non indigemus ergo singularibus IP inscriptionibus: Firebase clavium singulares valores (similis nominibus domain) sufficientes sunt ad singulares pares dignoscendis, et singuli pares localiter assignati "fake" IP inscriptiones unicuique clavis interpretandae sunt. Hoc omnino excludit necessitatem missionis globalis IP electronicae, quae munus non leve est.

Hic est minimum API opus efficiendi:

// 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 Simplex et similis Posix Basibus API, sed paucas differentias praecipuas habet; callbacks logging assignans loci IPS et hospites piger.

Perscriptum Callbacks

Etsi programmatis originalis I/O non-obturans utitur, signum restituendum est ut in navigatro interretiali currat.

Cuius rei causa est, quia eventus ansa in navigatro abscondita est a programmatis (ne JavaScript vel WebAssembly).

In ambitu nativo codice sic scribere possumus

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

Si ansa eventus nobis absconditus est, necesse est nos eam in aliquid simile vertere;

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

Locus IP assignment

IDs nodi in nostro "rete" non sunt IP inscriptiones, sed claves Firebase (sunt chordae quae hoc modo spectant; -LmEC50PYZLCiCP-vqde ).

Hoc opportunum est quod non opus est mechanismo ad IPs assignandos et eorum singularitatem inprimendam (ac disponendi post clientem disiunctis), sed saepe necessarium est ut pares numerorum valore cognoscantur.

Haec prorsus sunt quae functiones adhibentur. resolve и reverseResolve: Applicatio aliquo modo recipit valorem chordae clavis (per usoris input vel per servo domini), eamque ad IP oratio ad usum internum convertere potest. Ceteri API etiam hunc valorem pro chorda simplicitate accipiunt.

Hoc simile est cum DNS lookup, sed in cliens localiter praestitit.

Hoc est, IP inscriptiones inter clientes diversis communicari non possunt, et si aliqua species identitatis globalis desideratur, aliter generari debebit.

piger nexum

UDP nexum non indiget, sed, ut vidimus, WebRTC longam connexionis processum requirit antequam notitias inter duos pares transferre possit.

Si parem abstractionis velimus providere, (sendto/recvfrom cum paribus arbitrariis sine nexu praecedente), nexum "piger" (moratum) intra API praestare debent.

Hoc fit in communi communicatione inter "servatorem" et "clientem" cum utens UDP, et quid bibliotheca nostra facere debet:

  • Servo vocat bind()systema operandi narrare velle quod in portu determinato fasciculos recipere velit.

Sed apertam portum ad Firebase sub clavi servo edemus et res in subtrio suo audiemus.

  • Servo vocat recvfrom()in hunc portum venientes ab aliquo hospitio excipientes.

In casu nostro, necesse est ut venientes queue ex fasciculis ad hunc portum missis reprimantur.

Portus quisque suam queue habet, et portum principium ac destinatum addimus ad principium WebRTC datagrammatum, ut sciamus quem queue progrediamur cum novus fasciculus advenit.

Vocatio non interclusio est, quare si fasciculi non sunt, simpliciter -1 et pone errno=EWOULDBLOCK.

  • Cliens IP et portum accipit aliquo exteriori instrumento servitoris et vocat sendto(). Hoc etiam facit vocationem internam. bind()ergo sequens recvfrom() responsionem recipiet sine ligamento expresse exsequens.

In casu nostro, cliens exterius clavem nervum accipit et munere utitur resolve() IP oratio obtinere.

Hoc loco handshake WebRTC inchoamus si duo pares inter se nondum conexi sunt. Nexus ad diversos portus eiusdem parium utuntur eodem WebRTC DataChannel.

Nos quoque indirecta praestare bind()ut servo reconnect potest in altera sendto() si ob aliquam causam clauditur.

Servus notificatur nexus huius cum clientis SDP scribens offerre sub servo porti informationis in Firebase, et minister cum responsione sua ibi respondet.

Figura infra exemplum relatum ostendit profluenti pro nervum schematis et nuntii primi e cliente ad server transmissionem:

Ludum lusorium ex C ++ portans ad telam cum Cheerp, WebRTC et Firebase
Integram tabulam nexum tempus inter clientem et servo

conclusio,

Si hoc longe legisti, probabiliter es interested in actione theoria perspiciendi. In ludo ludere potest teeworlds.leaningtech.com, tempta id!


Amica par inter collegas suos

In codice network bibliotheca gratis praesto est at Github. Coniunge sermonem in nostro alveo ad Gitter!

Source: www.habr.com

Add a comment