WebRTC tehnologija: audio i video ćaskanje u pretraživaču. P2P video chat baziran na WebRTC WebRTC od strane web programera

Većina materijala na WebRTC fokusira se na nivo aplikacije pisanja koda i ne doprinosi razumijevanju tehnologije. Pokušajmo ići dublje i saznati kako dolazi do povezivanja, koji je deskriptor sesije i kandidati, šta su STUN i TURN server.

WebRTC

Uvod

WebRTC je tehnologija zasnovana na pretraživaču koja vam omogućava da povežete dva klijenta za prenos video podataka. Glavne karakteristike su interna podrška pretraživača (nema potrebe za ugrađenim tehnologijama trećih strana kao npr adobe flash) i mogućnost povezivanja klijenata bez korištenja dodatnih servera - konekcija peer-to-peer(Dalje, p2p).

Uspostavite vezu p2p- prilično težak zadatak, budući da računari nemaju uvijek javnu IP adrese, odnosno adrese na Internetu. Zbog male količine IPv4 adrese (i za sigurnosne svrhe) razvijen je mehanizam NAT, koji vam omogućava da kreirate privatne mreže, na primer, za kućnu upotrebu. Mnogi kućni ruteri sada podržavaju NAT i zahvaljujući tome, svi kućni uređaji imaju pristup Internetu, iako Internet provajderi obično daju takav pristup IP adresa. javnosti IP Adrese su jedinstvene na Internetu, ali privatne adrese nisu. Zato se povežite p2p- teško.

Da biste ovo bolje razumjeli, razmotrite tri situacije: oba čvora su na istoj mreži (Slika 1), oba čvora su u različitim mrežama (jedan privatni, drugi javni) (Slika 2) i oba čvora su u različitim privatnim mrežama sa istim IP adrese (Slika 3).

Slika 1: Oba čvora na istoj mreži

Slika 2: Čvorovi na različitim mrežama (jedan privatni, jedan javni)

Slika 3: Čvorovi u različitim privatnim mrežama, ali sa brojčano jednakim adresama

Na gornjim slikama, prvo slovo u dvoznakovnoj notaciji označava tip čvora (p = peer, r = ruter). Na prvoj slici situacija je povoljna: čvorovi u njihovoj mreži su u potpunosti identificirani po mreži IP adrese i stoga se mogu direktno povezati jedni s drugima. Na drugoj slici imamo dvije različite mreže koje imaju slične brojeve čvorova. Ovdje se pojavljuju ruteri (ruteri) koji imaju dva mrežna sučelja - unutar svoje mreže i izvan svoje mreže. Stoga imaju dva IP adrese. Redovni čvorovi imaju samo jedno sučelje preko kojeg mogu komunicirati samo na vlastitoj mreži. Ako prenose podatke nekome izvan svoje mreže, onda samo uz pomoć NAT unutar rutera (rutera) i stoga vidljiv drugima ispod IP adresa rutera je njihova vanjski IP adresa. Dakle, čvor p1 tu je enterijer IP = 192.168.0.200 i vanjski IP = 10.50.200.5 , pri čemu je posljednja adresa također eksterna za sve druge hostove na njegovoj mreži. Slična je situacija i za čvor p2. Stoga je njihova veza nemoguća ako je samo njihova unutrašnja (sopstvena) IP adrese. Možete koristiti eksterne adrese, odnosno adrese rutera, ali pošto svi čvorovi u istoj privatnoj mreži imaju istu eksternu adresu, to je prilično teško. Ovaj problem se rješava mehanizmom NAT

Šta će se dogoditi ako ipak odlučimo da čvorove povežemo preko njihovih internih adresa? Podaci neće napustiti mrežu. Da biste poboljšali učinak, možete zamisliti situaciju prikazanu na posljednjoj slici - oba čvora imaju iste interne adrese. Ako ih koriste za komunikaciju, tada će svaki čvor komunicirati sam sa sobom.

WebRTC uspješno se nosi sa takvim problemima koristeći protokol ICE, što, međutim, zahtijeva korištenje dodatnih servera ( STUN, TURN). Sve ovo u nastavku.

Dvije faze WebRTC-a

Za povezivanje dva čvora putem protokola WebRTC(ili jednostavno RTC ako su dva povezana iPhone„a) moraju se poduzeti neki preliminarni koraci za uspostavljanje veze. Ovo je prva faza - uspostavljanje veze. Druga faza je prijenos video podataka.

Treba odmah reći da, iako tehnologija WebRTC koristi razne komunikacijske metode u svom radu ( TCP i UDP) i ima fleksibilno prebacivanje između njih, ovu tehnologiju nema protokol za prosljeđivanje podataka veze. Nije iznenađujuće, jer spojite dva čvora p2p nije tako lako. Stoga je potrebno imati neke dodatno način prenosa podataka, koji nije povezan sa WebRTC. To može biti prijenos utičnice, protokol http, može čak biti i protokol SMTP ili Pošta Rusije. Ovaj mehanizam prenosa primarni podaci se pozivaju signal. Ne treba puno informacija prenositi. Svi podaci se prenose kao tekst i dijele se na dvije vrste − SDP i Ice Candidate. Prvi tip se koristi za uspostavljanje logičke veze, a drugi za fizičku. Više o tome kasnije, ali za sada je važno to zapamtiti WebRTCće nam dati neke informacije koje će se morati prenijeti na drugi čvor. Nakon što prenesemo sve potrebne informacije, čvorovi će se moći povezati i naša pomoć više neće biti potrebna. Dakle, mehanizam signalizacije treba da implementiramo odvojeno, će se koristiti samo kada je povezan, i neće se koristiti prilikom prijenosa video podataka.

Pogledajmo prvu fazu, fazu postavljanja veze. Sastoji se od nekoliko stavki. Razmotrite ovu fazu prvo za čvor koji inicira vezu, a zatim za onaj koji čeka.

  • Inicijator (pozivalac - pozivalac):
    1. Ponuda za početak prijenosa video podataka (createOffer)
    2. Dobivanje vašeg SDP SDP)
    3. Dobivanje vašeg Ledeni kandidat Ledeni kandidat)
  • Poziv na cekanju ( pozvani):
    1. Dobivanje lokalnog (vlastitog) medijskog toka i postavljanje za prijenos (getUserMediaStream)
    2. Primite ponudu da započnete prijenos video podataka i kreirate odgovor (createAnswer)
    3. Dobivanje vašeg SDP objekta i propuštajući ga kroz signalni mehanizam ( SDP)
    4. Dobivanje vašeg Ledeni kandidat objekata i njihov prijenos preko signalnog mehanizma ( Ledeni kandidat)
    5. Primanje udaljenog (stranog) medijskog toka i njegovo prikazivanje na ekranu (onAddStream)

Jedina razlika je u drugom paragrafu.

Uprkos očiglednoj složenosti koraka, postoje tri od njih: slanje sopstvenog medijskog toka (str. 1), postavljanje parametara veze (str. 2-4), primanje tuđeg medijskog toka (str. 5). Najteži je drugi korak, jer se sastoji iz dva dijela: uspostavljanja fizički i logicno veze. Prvi ukazuje put, duž koje paketi moraju ići da bi došli od jednog mrežnog čvora do drugog. Drugi ukazuje video/audio parametri- koji kvalitet koristiti, koje kodeke koristiti.

Mentalna pozornica createOffer ili createAnswer treba spojiti na faze prijenosa SDP i Ledeni kandidat objekata.

Osnovni entiteti

Medijski prijenosi (MediaStream)

Glavni entitet je medijski tok, odnosno tok video i audio podataka, slike i zvuka. Postoje dvije vrste medijskih tokova - lokalni i udaljeni. Lokalni prima podatke sa ulaznih uređaja (kamera, mikrofon), a daljinski preko mreže. Dakle, svaki čvor ima i lokalnu i udaljenu nit. AT WebRTC postoji interfejs za streamove medijski tok a tu je i podinterfejs LocalMediaStream posebno za lokalnu nit. AT JavaScript možete naići samo na prvu, i ako koristite lib jingle, onda se može naići i na drugu.

AT WebRTC postoji prilično zbunjujuća hijerarhija unutar niti. Svaki stream se može sastojati od nekoliko medijskih staza ( medijska staza), koji se pak može sastojati od nekoliko medijskih kanala ( MediaChannel). A može postojati i nekoliko samih medijskih tokova.

Razmotrimo sve po redu. Da bismo to učinili, imajmo na umu neki primjer. Recimo da želimo da prenesemo ne samo snimak sebe, već i video našeg stola, na kojem leži komad papira na kojem ćemo nešto napisati. Trebat će nam dva videa (mi + stol) i jedan audio (mi). Jasno je da nas i tabelu treba podijeliti u različite niti, jer ovi podaci vjerovatno slabo zavise jedni od drugih. Stoga ćemo imati dva medijski tok‘a – jedan za nas i jedan za sto. Prvi će sadržavati i video i audio podatke, a drugi samo video (slika 4).

Slika 4: Dva različita toka medija. Jedan za nas, jedan za naš sto

Odmah je jasno da bi medijski tok trebao barem uključiti mogućnost da sadrži podatke različitih tipova - video i audio. To se uzima u obzir u tehnologiji i stoga se svaka vrsta podataka implementira kroz medijsku stazu. medijska staza. Medijski zapis ima posebno svojstvo vrsta, koji određuje šta je pred nama - video ili audio (slika 5)

Slika 5: Medijski tokovi se sastoje od medijskih staza

Kako će se sve odvijati u programu? Napravićemo dva medijska toka. Zatim ćemo kreirati dva video zapisa i jedan audio zapis. Pristupimo kamerama i mikrofonu. Recimo svakoj stazi koji uređaj da koristi. Dodajmo video i audio zapis u prvi medijski tok i video zapis sa druge kamere u drugi medijski tok.

Ali kako da razlikujemo medijske tokove na drugom kraju veze? Da biste to učinili, svaki medijski tok ima svojstvo etiketa– oznaka toka, njen naziv (slika 6). Medijski zapisi imaju isto svojstvo. Iako se na prvi pogled čini da se video može razlikovati od zvuka na druge načine.

Slika 6: Medijski tokovi i staze su identifikovani oznakama

Dakle, i ako se medijski zapisi mogu identificirati preko oznake, zašto onda trebamo koristiti dva medijska toka za naš primjer, umjesto jednog? Na kraju krajeva, možete prenijeti jedan medijski tok i koristiti različite staze u njemu. Došli smo do važnog svojstva medijskih tokova – njih sinhronizovati medijske numere. Različiti medijski tokovi nisu međusobno sinkronizirani, ali unutar svakog medijskog toka sve pjesme igrao u isto vreme.

Dakle, ako želimo da se naše riječi, naše emocije na licu i naše parče papira puštaju u isto vrijeme, onda vrijedi koristiti jedan medijski stream. Ako to nije toliko važno, onda je isplativije koristiti različite tokove - slika će biti glatkija.

Ako numeru treba onemogućiti tokom prijenosa, tada možete koristiti svojstvo omogućeno medijske numere.

Na kraju, razmislite o stereo zvuku. Kao što znate, stereo zvuk su dva različita zvuka. I njih je potrebno poslati zasebno. Za to se koriste kanali. MediaChannel. Audio medijska numera može imati mnogo kanala (na primjer, 6 ako vam treba 5+1 audio). Unutar medijske staze, kanali, naravno, također sinhronizovano. Za video se obično koristi samo jedan kanal, ali se može koristiti nekoliko, na primjer, za reklamne preklapanja.

Da rezimiramo: koristimo medijski stream za prijenos video i audio podataka. Unutar svakog medijskog toka, podaci se sinkroniziraju. Možemo koristiti više medijskih tokova ako nam nije potrebna sinhronizacija. Unutar svakog medijskog toka postoje dvije vrste medijskih staza - za video i za audio. Obično nema više od dvije pjesme, ali može biti i više ako trebate prenijeti nekoliko različitih video zapisa (sagovornika i njegovog stola). Svaka numera se može sastojati od nekoliko kanala, koji se obično koriste samo za stereo zvuk.

U najjednostavnijoj situaciji video chata, imat ćemo jedan lokalni medijski stream, koji će se sastojati od dvije staze - video trake i audio zapisa, od kojih će se svaki sastojati od jednog glavnog kanala. Video zapis je odgovoran za kameru, audio zapis je za mikrofon, a medijski tok je kontejner za oboje.

Deskriptor sesije (SDP)

Različiti računari će uvijek imati različite kamere, mikrofone, video kartice i drugu opremu. Postoji mnogo opcija koje imaju. Sve ovo mora biti koordinirano za prijenos medijskih podataka između dva mrežna čvora. WebRTC radi to automatski i kreira poseban objekat - ručnik sesije SDP. Proslijedite ovaj objekt drugom čvoru i možete slati medijske podatke. Samo još nema veze s drugim čvorom.

Za to se koristi bilo koji signalni mehanizam. SDP može se prenijeti čak i kroz utičnice, čak i od strane osobe (saopćite to drugom čvoru telefonom), čak i ruskom poštom. Sve je vrlo jednostavno - dobićete gotovu SDP i treba ga poslati. I po prijemu s druge strane - transfer u odjel WebRTC. Rukohvat sesije se pohranjuje kao tekst i možete ga promijeniti u svojim aplikacijama, ali obično ne morate. Na primjer, kada povezujete desktop↔telefon, ponekad morate prisilno odabrati željeni audio kodek.

Obično, kada uspostavljate vezu, morate navesti neku adresu, na primjer URL. Ovdje nema potrebe za tim, jer ćete sami slati podatke na odredište putem mehanizma signalizacije. Da ukaže WebRTCšta želimo da instaliramo p2p vezu koju trebate pozvati funkciju createOffer. Nakon što pozovete ovu funkciju i date joj posebnu povratni poziv'a će biti stvoreno SDP objekt i proslijeđen na isti povratni poziv. Sve što se od vas traži je da ovaj objekat prenesete preko mreže na drugi čvor (sagovornika). Nakon toga, na drugom kraju, podaci će doći putem signalnog mehanizma, odnosno ovog SDP objekat. Ovaj deskriptor sesije je stran ovom čvoru i stoga nosi korisne informacije. Prijem ovog objekta je signal za početak veze. Stoga se morate složiti s ovim i pozvati funkciju createAnswer. To je potpuni analog createOffer . Nazad na svoje povratni pozivće proći lokalni deskriptor sesije i morat će biti proslijeđen nazad kroz mehanizam signalizacije.

Vrijedi napomenuti da funkciju createAnswer možete pozvati tek nakon što primite tuđu SDP objekt. Zašto? Jer lokalno SDP objekat koji će biti generisan kada se pozove createAnswer mora se oslanjati na daljinski upravljač SDP objekat. Samo u ovom slučaju moguće je uskladiti svoje video postavke sa postavkama sagovornika. Također, nemojte zvati createAnswer i createOffer dok se ne primi lokalni medijski stream - neće imati čemu pisati SDP objekat.

Od u WebRTC moguće je uređivati SDP objekt, onda nakon dobivanja lokalnog ručka, mora se postaviti. Može izgledati malo čudno proći WebRTCšta nam je ona sama dala, ali takav je protokol. Kada dobijete daljinski upravljač, morate ga također postaviti. Stoga morate instalirati dva deskriptora na jedan čvor - svoj i tuđi (odnosno lokalni i udaljeni).

Nakon takvih rukovanječvorovi znaju jedni druge o željama. Na primjer, ako je čvor 1 podržava kodeke A i B, i čvor 2 podržava kodeke B i C, onda, pošto svaki čvor zna svoje i tuđe deskriptore, oba čvora će izabrati kodek B(Slika 7). Logika veze je sada uspostavljena i medijski tokovi se mogu prenositi, ali postoji još jedan problem - čvorovi su i dalje povezani samo signalnim mehanizmom.


Slika 7: Dogovaranje kodeka

Kandidati (Ice kandidat)

Tehnologija WebRTC pokušava da nas zbuni svojom novom metodologijom. Prilikom uspostavljanja veze, adresa čvora sa kojim želite da se povežete nije navedena. Prvo instaliran logicno vezu, ne fizički, iako se oduvijek radilo suprotno. Ali to neće izgledati čudno, ako ne zaboravimo da koristimo signalni mehanizam treće strane.

Dakle, veza je već uspostavljena (logička veza), ali još uvijek nema načina da mrežni čvorovi prenose podatke. Nije sve tako jednostavno, ali počnimo jednostavno. Neka čvorovi budu u istoj privatnoj mreži. Kao što već znamo, oni se lako mogu povezati jedni s drugima putem svog internog IP adrese (ili možda neke druge, ako se ne koriste TCP/IP).

Kroz neke povratni poziv'i WebRTC kaže nam Ledeni kandidat objekata. Oni također dolaze u tekstualnom obliku i baš kao i kod deskriptora sesije, samo ih treba poslati kroz mehanizam signalizacije. Ako je deskriptor sesije sadržavao informacije o našim postavkama na nivou kamere i mikrofona, onda kandidati sadrže informacije o našoj lokaciji na mreži. Prosledite ih drugom čvoru i on će se moći fizički povezati s nama, a pošto već ima deskriptor sesije, može se logički povezati i podaci će „teći“. Ako nam ne zaboravi poslati svoj predmet kandidata, odnosno informaciju o tome gdje se nalazi u mreži, onda ćemo moći da se povežemo s njim. Ovdje napominjemo još jednu razliku u odnosu na klasičnu interakciju klijent-server. Komunikacija sa HTTP serverom se odvija prema shemi zahtjev-odgovor, klijent šalje podatke serveru, koji ih obrađuje i šalje putem adresa navedena u paketu zahtjeva. AT WebRTC trebam znati dvije adrese i povežite ih sa obe strane.

Razlika od ručki sesije je u tome što samo udaljene kandidate treba postaviti. Uređivanje je ovdje zabranjeno i ne može donijeti nikakvu korist. U nekim implementacijama WebRTC kandidate je potrebno postaviti tek nakon što se podese ručke sesije.

I zašto je postojao samo jedan deskriptor sesije, a može biti mnogo kandidata? Budući da se lokacija u mreži može odrediti ne samo po njenom internom IP adresu, ali i eksternu adresu rutera, i to ne obavezno jednu, kao i adrese TURN serveri. Ostatak paragrafa će biti posvećen detaljnoj raspravi o kandidatima i načinu povezivanja čvorova iz različitih privatnih mreža.

Dakle, dva čvora su u istoj mreži (slika 8). Kako ih prepoznati? Korišćenjem IP adrese. Nema drugog načina. Istina, još uvijek možete koristiti različite transporte ( TCP i UDP) i različitim portovima. Ovo su informacije koje se nalaze u objektu kandidata - IP, LUKA, TRANSPORT i neke druge. Neka, na primjer, koristi UDP transport i 531 luka.

Slika 8: Dva čvora su na istoj mreži

Onda ako smo u čvoru p1, onda WebRTC daće nam takav kandidatski objekat - . Ovo nije tačan format, već samo dijagram. Ako smo u čvoru p2, onda je kandidat . Preko signalnog mehanizma p1 primiće kandidata p2(tj. lokacija čvora p2, odnosno njegov IP i LUKA). Onda p1 može se povezati sa p2 direktno. tačnije, p1će poslati podatke na adresu 10.50.150.3:531 u nadi da će stići p2. Nije bitno da li ova adresa pripada čvoru p2 ili nekog posrednika. Važno je samo da će se podaci slati preko ove adrese i da mogu doći p2.

Dokle god su čvorovi u istoj mreži – sve je jednostavno i lako – svaki čvor ima samo jedan kandidatski objekat (uvijek znači svoju, odnosno svoju lokaciju u mreži). Ali biće mnogo više kandidata kada čvorovi budu unutra drugačije mreže.

Pređimo na komplikovaniji slučaj. Jedan čvor će biti iza rutera (tačnije, iza NAT-a), a drugi čvor će biti u istoj mreži sa ovim ruterom (na primjer, na Internetu) (slika 9).

Slika 9: Jedan host iza NAT-a, drugi ne

Ovaj slučaj ima posebno rješenje problema, koje sada razmatramo. Kućni ruter obično sadrži tablicu NAT. Ovo je poseban mehanizam dizajniran da omogući pristup čvorovima unutar privatne mreže rutera, na primjer, web stranicama.

Pretpostavimo da je web server direktno povezan na Internet, odnosno da ima javni IP* adresa. Neka bude čvor p2. Knot p1(web klijent) šalje zahtjev na adresu 10.50.200.10 . Prvo, podaci idu na ruter r1, odnosno na njegovom enterijer interfejs 192.168.0.1 . Nakon toga, ruter pamti izvornu adresu (adresu p1) i unosi ga u posebnu tabelu NAT, zatim mijenja izvornu adresu u svoju ( p1 r1). Nadalje, prema vanjski interfejs, ruter šalje podatke direktno na web server p2. Web server obrađuje podatke, generiše odgovor i šalje ga nazad. Šalje na ruter r1, jer je on taj koji je u povratnoj adresi (ruter je promijenio adresu u svoju). Ruter prima podatke, gleda u tabelu NAT i šalje podatke čvoru p1. Ruter ovdje djeluje kao posrednik.

Ali šta ako nekoliko čvorova iz interne mreže pristupi vanjskoj mreži u isto vrijeme? Kako će ruter razumjeti kome treba poslati odgovor? Ovaj problem je riješen sa luke. Kada ruter zamijeni adresu hosta svojom, on također zamjenjuje port. Ako dva čvora pristupaju Internetu, tada ruter zamjenjuje njihove izvorne portove razne. Zatim, kada se paket sa web servera vrati na ruter, ruter će razumeti port kome je ovaj paket dodeljen. Primjer je ispod.

Nazad na tehnologiju WebRTC, odnosno na njegov dio koji koristi ICE protokol (dakle Ice kandidati). Knot p2 ima jednog kandidata (njegova lokacija u mreži - 10.50.200.10 ), i čvor p1, koji se nalazi iza rutera sa NAT-om, imat će dva kandidata - lokalni ( 192.168.0.200 ) i kandidat za ruter ( 10.50.200.5 ). Prvi nije koristan, ali se ipak generira, jer WebRTC još ne zna ništa o udaljenom hostu - može ili ne mora biti na istoj mreži. Drugi kandidat će dobro doći, a kao što već znamo, luka će igrati važnu ulogu (proći NAT).

Unos tabele NAT generira se samo kada podaci izlaze iz interne mreže. Dakle, čvor p1 mora prvo prenijeti podatke i tek nakon toga podatke čvora p2 može doći do čvora p1.

Na praksi oba čvoraće biti iza NAT. Za kreiranje unosa u tabeli NAT svaki ruter, čvorovi moraju poslati nešto udaljenom čvoru, ali ovaj put ni prvi ne može doći do drugog, niti obrnuto. To je zbog činjenice da čvorovi ne poznaju svoj vanjski IP adrese, a slanje podataka na interne adrese je besmisleno.

Međutim, ako su vanjske adrese poznate, tada će se veza lako uspostaviti. Ako prvi čvor pošalje podatke ruteru drugog čvora, tada će ih ruter zanemariti, budući da je njegova tablica NAT dok je prazna. Međutim, u ruteru prvog čvora u tabeli NAT postojala je potreba za zapisnikom. Ako sada drugi čvor šalje podatke ruteru prvog čvora, onda će ih ruter uspješno prenijeti do prvog čvora. Sada sto NAT drugi ruter ima podatke koji su vam potrebni.

Problem je u tome da se upoznate sa svojim eksternim IP adresu, potreban vam je čvor koji se nalazi na zajedničkoj mreži. Za rješavanje ovog problema koriste se dodatni serveri koji su direktno povezani na Internet. Uz njihovu pomoć kreiraju se i dragoceni zapisi u tabeli. NAT.

STUN i TURN serveri

Prilikom inicijalizacije WebRTC dostupan STUN i TURN servere, koje ćemo nazivati ICE serveri. Ako serveri nisu navedeni, onda samo čvorovi u istoj mreži (povezani na nju bez NAT). Odmah treba napomenuti da za 3g-mreže se moraju koristiti TURN serveri.

STUN server je samo server na Internetu koji vraća povratnu adresu, odnosno adresu hosta pošiljaoca. Čvor iza rutera pristupa STUN server kroz koji treba proći NAT. Paket koji je došao STUN server, sadrži izvornu adresu - adresu rutera, odnosno eksternu adresu našeg čvora. Ova adresa STUN server i šalje nazad. Dakle, čvor dobija svoj eksterni IP adresu i port preko kojeg je dostupan iz mreže. dalje, WebRTC korištenjem ove adrese kreira se dodatni kandidat (adresa eksternog rutera i port). Sada u tabeli NAT ruter ima unos koji prosljeđuje pakete poslane ruteru na traženom portu do našeg čvora.

Pogledajmo ovaj proces na primjeru.

Primjer (funkcionisanje STUN servera)

STUN server će biti označen sa s1. Ruter, kao i prije, kroz r1, i čvor kroz p1. Takođe ćete morati da pratite tabelu NAT- označimo ga kao r1_nat. Štaviše, ova tabela obično sadrži mnogo unosa iz različitih čvorova podmreže - oni neće biti dati.

Dakle, na početku imamo prazan sto r1_nat.

Tabela 2: Zaglavlje paketa

Knot p1šalje ovaj paket ruteru r1(bez obzira kako, različite tehnologije se mogu koristiti u različitim podmrežama). Ruter treba da izvrši zamjenu izvorne adrese src IP, pošto adresa navedena u paketu očigledno nije pogodna za eksternu podmrežu, štaviše, adrese iz ovog opsega su rezervisane, a ni jedna adresa na Internetu nema takvu adresu. Ruter vrši zamjenu u paketu i kreira novi unos u svojoj tabeli r1_nat. Da bi to učinio, mora smisliti broj porta. Podsjetimo da, budući da nekoliko čvorova unutar podmreže može pristupiti vanjskoj mreži, onda u tabeli NAT dodatne informacije moraju biti pohranjene tako da ruter može odrediti kojem od ovih nekoliko domaćina je namijenjen povratni paket sa servera. Neka ruter smisli port 888 .

Promijenjeno zaglavlje paketa:

Tabela 4: NAT tabela ažurirana novim unosom

Evo IP adresa i port za podmrežu su potpuno isti kao originalni paket. Zaista, na povratku, moramo imati način da ih potpuno obnovimo. IP adresa za eksternu mrežu je adresa rutera, a port je promenjen u onaj koji je izmislio ruter.

Pravi port na koji je čvor p1 prihvata vezu - ovo, naravno, 35777 , ali server šalje podatke na fiktivno luka 888 , koju će ruter promijeniti u realnu 35777 .

Dakle, ruter je promijenio izvornu adresu i port u zaglavlju paketa i dodao unos u tabelu NAT. Sada se paket šalje preko mreže na server, odnosno čvor s1. na ulazu, s1 ima ovaj paket:

src IP Src PORT Odredišna IP adresa DEST PORT
10.50.200.5 888 12.62.100.200 6000

Tabela 5: STUN server je primio paket

Ukupno STUN server zna da je primio paket sa adrese 10.50.200.5:888 . Sada server šalje ovu adresu nazad. Vrijedi se ovdje zaustaviti i ponovo razmotriti ono što smo upravo razmotrili. Gornje tabele su dio header paket, nikako iz njega sadržaj. O sadržaju nismo razgovarali, jer on nije toliko važan - to je nekako opisano u protokolu STUN. Sada ćemo uz naslov razmotriti i sadržaj. Biće jednostavno i sadržaće adresu rutera - 10.50.200.5:888 iako smo ga uzeli iz header paket. Ovo se ne radi često, obično protokoli ne mare za informacije o adresama čvorova, važno je samo da se paketi isporuče na odredište. Ovdje razmatramo protokol koji uspostavlja putanju između dva čvora.

Dakle, sada imamo drugu grupu koja ide u suprotnom smjeru:

Tabela 7: STUN server šalje paket sa ovim sadržajem

Zatim paket putuje kroz mrežu dok ne stigne do eksternog interfejsa rutera r1. Ruter razumije da paket nije namijenjen njemu. Kako on to razume? Ovo se može naći samo u luci. Port 888 on ne koristi u svoje lične svrhe, već koristi za mehanizam NAT. Stoga ruter gleda u ovu tabelu. Gleda u kolonu Eksterni PORT i traži niz koji odgovara DEST PORT iz dolaznog paketa, tj 888 .

interni IP Interni PORT eksterna IP adresa Eksterni PORT
192.168.0.200 35777 10.50.200.5 888

Tabela 8: NAT tablica

Imamo sreće da takva linija postoji. Da nije bilo sreće, onda bi paket jednostavno bio odbačen. Sada morate razumjeti koji od čvorova podmreže treba poslati ovaj paket. Nemojmo žuriti, hajde da ponovimo važnost portova u ovom mehanizmu. U isto vrijeme, dva čvora na podmreži mogu slati zahtjeve vanjskoj mreži. Zatim, ako je za prvi čvor ruter došao do porta 888 , onda bi za drugi smislio port 889 . Pretpostavimo da se to dogodilo, odnosno stol r1_nat izgleda ovako:

Tabela 10: Adresa prijemnika koji lažira ruter

src IP Src PORT Odredišna IP adresa DEST PORT
12.62.100.200 6000 192.168.0.200 35777

Tabela 11: Ruter je promijenio adresu prijemnika

Paket uspješno stiže u čvor p1 a gledajući sadržaj paketa, čvor uči o njegovom vanjskom IP adresa, odnosno adresa rutera u eksternoj mreži. Takođe zna port kroz koji ruter prolazi NAT.

Šta je sledeće? Kakva je korist od svega ovoga? Pogodnost je unos u tabeli r1_nat. Ako će sada neko poslati na ruter r1 port paket 888 , tada će ruter proslediti ovaj paket hostu p1. Tako je stvoren mali uski prolaz do skrivenog čvora p1.

Iz gornjeg primjera možete dobiti neku ideju o tome kako funkcionira. NAT i suštinu STUN server. Generalno, mehanizam ICE i STUN/TURN serveri su samo usmjereni na prevazilaženje ograničenja NAT.

Između čvora i servera može biti više od jednog rutera, ali nekoliko. U tom slučaju, čvor će dobiti adresu rutera koji prvi ulazi u istu mrežu kao i server. Drugim riječima, dobijamo adresu rutera na koji je povezan STUN server. Za p2p komunikacija je upravo ono što nam treba, ako ne zaboravimo činjenicu da će u svakom ruteru linija koja nam je potrebna biti dodana u tabelu NAT. Dakle, povratak će opet biti jednako glatki.

TURN server je poboljšan STUN server. Iz ovoga odmah slijedi da bilo koji TURN server može da radi i kako STUN server. Međutim, postoje i prednosti. Ako a p2p komunikacija nije moguća (kao u 3g mreže), tada se server prebacuje u režim repetitora ( relej), odnosno radi kao posrednik. Naravno, o bilo kom p2p onda to nije pitanje, već izvan okvira mehanizma ICEčvorovi misle da komuniciraju direktno.

U kojim slučajevima je to neophodno TURN server? Zašto nije dovoljno STUN serveri? Činjenica je da postoji nekoliko vrsta NAT. Zamjenjuju iste IP adresu i port, ali neki od njih imaju ugrađenu dodatnu zaštitu od “falsifikovanja”. Na primjer, u simetrično sto NAT Sačuvana su još 2 parametra - IP i port udaljenog hosta. Paket iz vanjske mreže prolazi NAT na internu mrežu samo ako se adresa izvora i port poklapaju sa onima navedenim u tabeli. Dakle, fokus STUN server ne radi - tabela NAT pohranjuje adresu i port STUN servera i kada ruter primi paket od WebRTC sagovornika, on ga odbacuje, jer je “falsifikovan”. On nije došao iz STUN server.

Na ovaj način TURN server je potreban kada su oba sagovornika iza simetrično NAT(svako za svoje).

Kratak sažetak

Evo nekoliko izjava o entitetima WebRTCšto se uvek mora imati na umu. Oni su detaljno opisani gore. Ako vam bilo koja od izjava nije potpuno jasna, ponovo pročitajte relevantne odlomke.

  • medijski tok
    • Video i audio podaci su upakovani u medijske tokove
    • Medijski tokovi sinkroniziraju medijske staze koje čine
    • Različiti medijski tokovi nisu sinhronizirani
    • Medijski streamovi mogu biti lokalni i udaljeni, kamera i mikrofon su obično povezani na lokalni, udaljeni primaju podatke iz mreže u šifriranom obliku
    • Postoje dvije vrste medijskih zapisa - za video i za audio.
    • Medijski zapisi imaju mogućnost uključivanja/isključivanja
    • Medijske staze se sastoje od medijskih kanala
    • Medijske numere sinhronizuju medijske kanale koji se sastoje
    • Medijski tokovi i medijski zapisi imaju oznake po kojima se mogu razlikovati
  • Session handle
    • Deskriptor sesije se koristi za logičko povezivanje dva mrežna čvora
    • Deskriptor sesije pohranjuje informacije o dostupnim metodama kodiranja za video i audio podatke.
    • WebRTC koristi vanjski mehanizam signalizacije - zadatak prosljeđivanja deskriptora sesije ( sdp) pada na aplikaciju
    • Mehanizam logičkog povezivanja sastoji se od dvije faze - prijedloga ( ponuda) i odgovor ( odgovori)
    • Generiranje deskriptora sesije nije moguće bez upotrebe lokalnog medijskog toka u slučaju ponude ( ponuda) i nije moguće bez korištenja deskriptora udaljene sesije u slučaju odgovora ( odgovori)
    • Rezultirajući deskriptor se mora dati implementaciji WebRTC, i nije važno da li je ovaj ručnik dobiven daljinski ili lokalno iz iste implementacije WebRTC
    • Moguće je malo urediti deskriptor sesije
  • Kandidati
    • kandidat ( Ledeni kandidat) je adresa čvora u mreži
    • Adresa čvora može biti vaša vlastita, ili može biti adresa rutera ili TURN serveri
    • Kandidata uvijek ima mnogo
    • Kandidat se sastoji od IP adresa, luka i vrsta prevoza ( TCP ili UDP)
    • Kandidati se koriste za uspostavljanje fizičke veze između dva čvora u mreži
    • Kandidate je potrebno poslati i putem signalnog mehanizma
    • Kandidati također moraju proći implementacije WebRTC, ali samo daljinski
    • U nekim implementacijama WebRTC Kandidati se mogu položiti samo nakon što je postavljen deskriptor sesije
  • STUN/TURN/ICE/NAT
    • NAT– mehanizam za omogućavanje pristupa eksternoj mreži
    • Kućni ruteri podržavaju posebnu tablicu NAT
    • Ruter zamjenjuje adrese u paketima - izvornu adresu svojom, u slučaju da paket ide na vanjsku mrežu, i adresu primatelja sa adresom domaćina u internoj mreži, ako je paket došao sa vanjske mreže
    • Za pružanje višekanalnog pristupa vanjskoj mreži NAT koristi portove
    • ICE- premosni mehanizam NAT
    • STUN i TURN serveri - pomoćni serveri za zaobilaženje NAT
    • STUN server vam omogućava da kreirate potrebne unose u tabeli NAT, a također vraća vanjsku adresu čvora
    • TURN server generalizuje STUN mehanizam i čini da uvijek radi
    • U najgorim slučajevima TURN server se koristi kao posrednik ( relej), to je p2p pretvara u vezu klijent-server-klijent.

Evropski korisnici interneta podijeljeni su u dva dijela: prema istraživanju Instituta za analizu javnog mnijenja u Allenbachu (Nemačka), Skype, chat i sistemi za instant poruke postali su sastavni dio svakodnevnog života za 16,5 miliona odraslih i djece, 9 miliona koriste ove usluge od slučaja do slučaja, a 28 miliona ih ne dira.

Situacija se može promijeniti jer je sada Firefox integriran komunikacijska tehnologija u realnom vremenu (WebRTC), kao i samog klijenta. Pokretanje audio i video chata sada nije ništa teže od otvaranja web stranice. Servisi kao što su Facebook i Skype se, s druge strane, oslanjaju na rješenja koja koriste poseban klijent i kreiraju nalog.

WebRTC nije samo jednostavan za korištenje. Ova metoda vam čak omogućava postavljanje direktnu vezu između dva pretraživača. Dakle, audio i video podaci ne prolaze kroz server na kojem može doći do zagušenja ili gdje administrator nije posebno osjetljiv u pogledu privatnosti ili zaštite podataka. Uz direktnu vezu, WebRTC ne zahtijeva registraciju ili nalog na bilo kojoj usluzi.

Da biste započeli razgovor, potrebno je samo da pratite link. Komunikacija ostaje privatna jer je tok podataka šifriran. Komunikaciju u realnom vremenu putem pretraživača, Google je počeo aktivno da se bavi još 2011. godine, kada je objavio izvorni kod svoje WebRTC implementacije.

Ubrzo nakon toga, Chrome i Firefox dobili su vlastite WebRTC motore. Trenutno su njihove mobilne verzije opremljene i ovom tehnologijom i WebView 3.6 motorom instaliranim sa Androidom 5.0, koji koriste aplikacije.

Za komunikaciju u realnom vremenu, odgovarajući JavaScript interfejsi moraju biti implementirani u web preglednik. Uz GetUserMedia, softver omogućava snimanje iz audio i video izvora, tj. web kamere i mikrofona. RTCPeerConnection je odgovoran za uspostavljanje veze, kao i za samu komunikaciju.

Paralelno sa integracijom pretraživača, radna grupa World Wide Web Consortium (W3C) gura proces standardizacije WebRTC-a. Trebalo bi da bude završen 2015. godine.

WebRTC se zadovoljava s malo

Korišćenje WebRTC usluge ne zahteva mnogo resursa, pošto server povezuje samo prijatelje. Uspostavljanje veze također nije posebno teško. Prvo, pretraživač signalizira WebRTC serveru da planira pokrenuti poziv. Prima HTTPS vezu sa servera - veza je šifrovana. Korisnik šalje ovu vezu svom sagovorniku. Pregledač tada traži od korisnika dozvolu za pristup web kameri i mikrofonu.

Da bi uspostavio direktnu striming vezu sa drugom stranom, pretraživač prima njegovu IP adresu i konfiguracione podatke od WebRTC usluge. Prijateljev web pretraživač radi isto.

Kako bi streaming veza funkcionirala nesmetano i kvalitetno, u pretraživaču rade tri motora. Dvije od njih optimiziraju i komprimiraju audio i video podatke, treći je odgovoran za njihov transport. Šalje podatke putem SRTP protokol(Secure Real-time Transport Protocol), koji omogućava šifrovani streaming u realnom vremenu.

Ako direktna veza ne uspije, WebRTC traži drugu putanju. Na primjer, ovo se dešava kada mrežne postavke sprječavaju STUN server da prijavi IP adresu. WebRTC standard predviđa da će se u ovom slučaju razgovor odvijati, ali uz posredno uključivanje TURN servera (Traversal Using Relays around NAT). Dakle, na web stranici netscan.co možete provjeriti da li je WebRTC implementiran na vašem računalu i s vašim pristupom webu.

Kako se uspostavlja veza

Prvo morate registrovati razgovor (1). WebRTC servis pruža vezu koju je potrebno poslati sagovorniku. Pretraživač, koristeći STUNserver, saznaje svoju IP adresu (2), šalje je servisu i prima IP partnera za uspostavljanje direktne veze (3). Ako STUN ne uspije, razgovor se preusmjerava pomoću TURN servera (4).

Komunikacija pomoću WebRTC tehnologije u pretraživaču se pokreće pomoću JavaScript koda. Nakon toga, tri motora su odgovorna za komunikaciju: glasovni i video motori prikupljaju multimedijalne podatke sa web kamere i mikrofona, a transportni motor kombinuje informacije i šalje stream u šifriranom obliku koristeći Secure Real-time Protocol (SRTP).

Koji pretraživači rade sa WebRTC-om

Chrome i Firefox opremljeni su WebRTC motorom koji koristi usluge kao što je talky.io. Mozilla pretraživač može raditi direktno sa svojim klijentom.

Google i Mozilla nastavljaju da razvijaju ideju komunikacije u realnom vremenu: Chrome može ugostiti WebRTC konferenciju sa više učesnika, a novi Hello klijent u Firefoxu razvijen je uz pomoć podružnice telekomunikacionog giganta Telefonica. Apple za sada ostaje po strani, WebRTC još ne treba očekivati ​​u Safariju. Međutim, postoji mnogo alternativnih iOS aplikacija i dodataka za Safari.

Microsoft ide malo drugačijim putem. Kao vlasnik konkurentnog Skype servisa, ova kompanija neće tako lako kapitulirati pred WebRTC-om. Umjesto toga, Microsoft razvija tehnologiju pod nazivom ORTC (Object Real-Time Communications) za Internet Explorer.

Razlike u odnosu na WebRTC, kao što su različiti kodeci i protokoli za uspostavljanje kontakta sa serverom, su male i, tokom vremena, vjerovatno će postati dodatak WebRTC standardu, koji će uključivati ​​ove razlike. Dakle, samo Apple ostaje iza - kao i obično.

Fotografija: proizvodne kompanije; goodluz/Photolia.com

Tehnologije za pozivanje iz pretraživača stare su mnogo godina: Java, ActiveX, Adobe Flash... U posljednjih nekoliko godina postalo je jasno da dodaci i lijevo virtuelne mašine ne blistaju praktičnošću (zašto da instaliram bilo šta na sve?) i, najvažnije, sigurnost. sta da radim? Postoji izlaz!

Do nedavno se u IP mrežama koristilo nekoliko protokola za IP telefoniju ili video: SIP, najčešći protokol koji dolazi sa scene, H.323 i MGCP, Jabber/Jingle (koristi se u Gtalk), poluotvoreni Adobe RTMP* i, naravno, zatvoren Skype. Projekt WebRTC, koji je pokrenuo Google, pokušava da preokrene svijet IP i web telefonije tako što zastari sve softphone, uključujući Skype. WebRTC ne samo da implementira sve komunikacijske mogućnosti direktno unutar pretraživača, koji je sada instaliran na gotovo svakom uređaju, već istovremeno pokušava riješiti i opštiji zadatak komunikacije između korisnika pretraživača (razmjena različitih podataka, prevođenje ekrana, suradnja s dokumentima i mnogo više).

WebRTC od strane web programera

Sa stanovišta web programera, WebRTC se sastoji od dva glavna dijela:

  • upravljanje medijskim tokovima iz lokalnih resursa (kamera, mikrofon ili ekran lokalnog računara) implementirano je metodom navigator.getUserMedia, koja vraća MediaStream objekat;
  • ravnopravne komunikacije između uređaja koji generiraju medijske tokove, uključujući definiciju komunikacijskih metoda i njihov direktan prijenos - RTCPeerConnection objekti (za slanje i primanje audio i video tokova) i RTCDataChannel (za slanje i primanje podataka iz pretraživača).

Šta da radimo?

Shvatit ćemo kako organizirati najjednostavniji video chat za više igrača između pretraživača baziran na WebRTC-u koristeći web utičnice. Počnimo da eksperimentišemo sa Chrome/Chromium-om, kao najnaprednijim pretraživačima u smislu WebRTC-a, iako ih je Firefox 22, objavljen 24. juna, skoro sustigao. Mora se reći da standard još nije usvojen, a API se može mijenjati od verzije do verzije. Svi primjeri su testirani u Chromiumu 28. Radi jednostavnosti, nećemo pratiti čistoću koda i kompatibilnost među pretraživačima.

medijski tok

Prva i najjednostavnija WebRTC komponenta je MediaStream. On omogućava pretraživaču pristup medijskim tokovima sa kamere i mikrofona lokalnog računara. U Chromeu to zahtijeva pozivanje funkcije navigator.webkitGetUserMedia() (jer standard još nije finaliziran, sve funkcije dolaze s prefiksom, au Firefoxu ista funkcija se zove navigator.mozGetUserMedia()). Kada se pozove, od korisnika će biti zatraženo da dozvoli pristup kameri i mikrofonu. Nastavak poziva bit će moguć tek nakon što korisnik da svoj pristanak. Parametri potrebnog medijskog toka i dvije funkcije povratnog poziva prosljeđuju se kao parametri ovoj funkciji: prva će biti pozvana u slučaju uspješnog pristupa kameri/mikrofonu, druga - u slučaju greške. Prvo, napravimo HTML datoteku rtctest1.html sa dugmetom i elementom

WebRTC - prvo poznanstvo

Microsoft CU-RTC-Web

Microsoft ne bi bio Microsoft da nije odmah objavio vlastitu nekompatibilnu prilagođenu varijantu pod nazivom CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web.htm) kao odgovor na Googleovu inicijativu . Iako udio IE, ionako mali, i dalje opada, broj korisnika Skype-a daje Microsoftu nadu da će pogurati Google, a može se pretpostaviti da će se ovaj standard koristiti u pretraživačkoj verziji Skypea. Google standard se prvenstveno fokusira na komunikaciju između pretraživača; u isto vrijeme, najveći dio govornog prometa i dalje ostaje u konvencionalnoj telefonskoj mreži, a pristupnici između nje i IP mreža su potrebni ne samo radi lakšeg korištenja ili brže distribucije, već i kao sredstvo monetizacije koje će omogućiti većem broju igrača da razvijati ih. Pojava drugog standarda ne samo da može dovesti do neugodne potrebe programera da podrže dvije nekompatibilne tehnologije odjednom, već i u budućnosti korisniku pružiti širi izbor mogućih funkcionalnosti i dostupnih tehničkih rješenja. Sačekaj i vidi.

Omogući lokalnu nit

Unutrašnje oznake U našoj HTML datoteci, deklarirajmo globalnu varijablu za medijski tok:

VarlocalStream = null;

Prvi parametar metode getUserMedia je specificiranje parametara traženog medijskog toka - na primjer, jednostavno omogućite audio ili video:

Var streamConstraints = ( "audio": true, "video": true ); // Zahtjev za pristup zvuku i videu

Ili navedite dodatne opcije:

Var streamConstraints = ( "audio": true, "video": ( "obavezno": ( "maxWidth": "320", "maxHeight": "240", "maxFrameRate": "5" ), "opciono": ) );

Drugi parametar getUserMedia metodi je prosljeđivanje funkcije povratnog poziva koja će biti pozvana ako bude uspješna:

Funkcija getUserMedia_success(stream) ( console.log("getUserMedia_success():", stream); localVideo1.src = URL.createObjectURL(stream); // Priložite medijski tok HTML elementu

Treći parametar je funkcija povratnog poziva, rukovalac greškama koji će biti pozvan u slučaju greške.

Funkcija getUserMedia_error(error) ( console.log("getUserMedia_error():", greška); )

Stvarni poziv metodi getUserMedia - traženje pristupa mikrofonu i kameri kada se pritisne prvo dugme

Funkcija getUserMedia_click() ( console.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints, getUserMedia_success, getUserMedia_error); )

Nije moguće pristupiti medijskom toku iz datoteke otvorenog lokalno. Ako pokušamo ovo da uradimo, dobijamo grešku:

NavigatorUserMediaError (šifra: 1, PERMISSION_DENIED: 1)"

Učitajmo rezultirajući fajl na server, otvorimo ga u pretraživaču i, kao odgovor na zahtjev koji se pojavi, dozvolimo pristup kameri i mikrofonu.

Možete odabrati kojim uređajima će Chrome pristupiti tako što ćete otići na Postavke, Prikaži vezu za napredne postavke, odjeljak Privatnost, dugme Sadržaj. U pretraživačima Firefox i Opera uređaji se biraju sa padajuće liste direktno kada im se odobri pristup.

Kada koristite HTTP protokol, dozvola će se tražiti svaki put kada se pristupi medijskom toku nakon učitavanja stranice. Prebacivanje na HTTPS omogućit će vam da jednom prikažete zahtjev, samo pri prvom pristupu medijskom streamu.

Obratite pažnju na pulsirajući krug u ikoni na kartici i ikonu kamere na desnoj strani adresne trake:

RTCMediaConnection

RTCMediaConnection - objekt dizajniran za uspostavljanje i prijenos medijskih tokova preko mreže između sudionika. Pored toga, ovaj objekat je odgovoran za generisanje opisa medijske sesije (SDP), dobijanje informacija o ICE kandidatima za prolazak kroz NAT ili firewall (lokalni i koji koriste STUN) i interakciju sa TURN serverom. Svaki učesnik mora imati jednu RTCMediaConnection po konekciji. Medijski tokovi se prenose preko šifrovanog SRTP protokola.

TURN servere

Postoje tri tipa ICE kandidata: host, srflx i relay. Host sadrži informacije dobijene lokalno, srflx je kako host izgleda na eksternom serveru (STUN), a relej je informacija za proxy saobraćaj preko TURN servera. Ako je naš čvor iza NAT-a, tada će kandidati za domaćine sadržavati lokalne adrese i biće beskorisni, srflx kandidati će pomoći samo sa određenim tipovima NAT-a i relej će biti posljednja nada za prolazak saobraćaja kroz posredni server.

Primjer ICE kandidata tipa host, sa adresom 192.168.1.37 i portom udp/34022:

A=kandidat:337499441 2 udp 2113937151 192.168.1.37 34022 tip host generacija 0

Opšti format za određivanje STUN/TURN servera:

Var serveri = ( "iceServers": [ ( "url": "stun:stun.stunprotocol.org:3478" ), ( "url": "turn: [email protected]:port", "credential": "password" ) ]);

Postoji mnogo javnih STUN servera na Internetu. Velika lista, na primjer, je . Nažalost, rješavaju premalo problema. Praktično ne postoje javni TURN serveri, za razliku od STUN-a. To je zbog činjenice da TURN server propušta medijske tokove kroz sebe, što može značajno opteretiti i mrežni kanal i sam server. Stoga je najlakši način da se povežete na TURN servere da ga sami instalirate (očigledno će vam trebati javni IP). Od svih servera, po mom mišljenju, najbolji je rfc5766-turn-server. Ispod njega se nalazi čak i gotova slika za Amazon EC2.

Sa TURN-om nije sve tako dobro kako bismo željeli, ali je u toku aktivan razvoj i nadam se da će nakon nekog vremena WebRTC, ako ne i Skype, po kvalitetu prolaska kroz translaciju adresa (NAT) i firewall-a, onda se barem primjetno približavaju.

RTCMediaConnection treba dodatni mehanizam za razmjenu kontrolnih informacija kako bi uspostavio vezu - iako generiše ove podatke, ne prenosi ih, a prijenos od strane drugih učesnika mora biti implementiran odvojeno.


Izbor metode prijenosa je odgovornost programera - barem ručno. Čim se razmijene potrebni podaci, RTCMediaConnection će automatski postaviti medijske tokove (ako je moguće, naravno).

model ponuda-odgovor

Za uspostavljanje i modificiranje medijskih tokova koriste se model ponude/odgovora (ponuda/odgovor; opisan u RFC3264) i SDP protokol (protokol opisa sesije). Koriste ih i SIP protokol. U ovom modelu razlikuju se dva agenta: Ponuđač - onaj koji generiše opis SDP sesije da bi kreirao novu ili modifikovao postojeću (Ponuda SDP), i Answerer - onaj koji prima opis SDP sesije od drugog agenta i odgovara na to sa svojim opisom sesije (Odgovor SDP). U isto vrijeme, specifikacija zahtijeva protokol višeg nivoa (na primjer, SIP ili vlastite preko web utičnice, kao u našem slučaju), koji je odgovoran za prijenos SDP-a između agenata.

Koji podaci moraju biti proslijeđeni između dvije RTCMediaConnections da bi mogli uspješno uspostaviti medijske tokove:

  • Prva strana koja inicira vezu formira Ponudu u kojoj prenosi SDP strukturu podataka (isti protokol se koristi za istu svrhu u SIP-u) opisujući moguće karakteristike medijskog toka koji će početi sa prijenosom. Ovaj blok podataka mora se prenijeti drugom učesniku. Drugi učesnik generiše odgovor sa svojim SDP-om i šalje ga prvom.
  • I prvi i drugi učesnik obavljaju proceduru za određivanje mogućih ICE kandidata, uz pomoć kojih drugi učesnik može da im prenese medijski tok. Kako su kandidati identifikovani, informacije o njima treba prenijeti drugom učesniku.

Formiranje ponude

Za formiranje Ponude potrebne su nam dvije funkcije. Prvi će biti pozvan u slučaju uspješnog formiranja. Drugi parametar metode createOffer() je funkcija povratnog poziva koja se poziva u slučaju greške tokom njenog izvršavanja (pod uslovom da je lokalni tok već dostupan).

Dodatno, potrebna su dva obrađivača događaja: onicecandidate kada je definiran novi ICE kandidat i onddstream kada je medijski tok povezan sa udaljene strane. Vratimo se na naš fajl. Dodajte u HTML nakon redova sa elementima

I nakon linije sa elementom


Takođe, na početku JavaScript koda, deklarisaćemo globalnu varijablu za RTCPeerConnection:

varpc1;

Kada pozivate RTCPeerConnection konstruktor, morate navesti STUN/TURN servere. Pogledajte bočnu traku za više detalja; sve dok su svi učesnici na istoj mreži, nisu potrebni.

var serveri = null;

Opcije za pružanje ponude SDP

var offerConstraints = ();

Prvi parametar metode createOffer() je funkcija povratnog poziva koja se poziva nakon uspješnog formiranja ponude

Funkcija pc1_createOffer_success(desc) ( console.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(desc); // Postavite RTCPeerConnection generiranu Ponudite SDP metod setLocalDescription. // Kada udaljena strana pošalje svoj odgovor SDP, morat će se postaviti pomoću metode setRemoteDescription // Dok se druga strana ne implementira, ne čini ništa // pc2_receivedOffer(desc); )

Drugi parametar je funkcija povratnog poziva koja će biti pozvana u slučaju greške

Funkcija pc1_createOffer_error(error)( console.log("pc1_createOffer_success_error(): error:", error); )

A mi ćemo deklarisati funkciju povratnog poziva koja će biti proslijeđena ICE kandidatima kako su definirani:

Funkcija pc1_onicecandidate(event)( if (event.candidate) ( console.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // Ne radite ništa dok se druga strana ne implementira // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

Kao i funkcija povratnog poziva za dodavanje medijskog toka sa daleke strane (za budućnost, pošto do sada imamo samo jednu RTCPeerConnection):

Funkcija pc1_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo1.src = URL.createObjectURL(event.stream); )

Kada kliknete na dugme “createOffer”, kreirajte RTCPeerConnection, postavite metode onicecandidate i onaddstream i zatražite formiranje SDP ponude pozivanjem metode createOffer():

Funkcija createOffer_click() ( console.log("createOffer_click()"); pc1 = novi webkitRTCPeerConnection(servers); // Kreirajte RTCPeerConnection pc1.onicecandidate = pc1_onicecandidate; // Funkcija povratnog poziva za obradu ICE kandidata pc1.1. / Funkcija povratnog poziva pozvana kada postoji medijski tok sa daleke strane, on još ne postoji pc1.addStream(localStream); // Proslijedite lokalni medijski tok (pod pretpostavkom da je već primljen) pc1.createOffer(// I zapravo zatražite formiranje Ponude pc1_createOffer_success , pc1_createOffer_error, offerConstraints); )

Sačuvajmo fajl kao rtctest2.html, stavimo ga na server, otvorimo ga u pretraživaču i vidimo u konzoli koji podaci se generišu tokom njegovog rada. Drugi video se još neće pojaviti, jer je samo jedan učesnik. Podsjetimo da je SDP opis parametara medijske sesije, dostupni kodeci, medijski streamovi i ICE kandidati su moguće opcije za povezivanje s ovim sudionikom.

Formiranje SDP-a Odgovora i razmjena ICE kandidata

I Ponuda SDP i svaki od ICE kandidata moraju biti proslijeđeni drugoj strani, i tamo, nakon što ih primi od RTCPeerConnection, pozvati metode setRemoteDescription za SDP ponude i addIceCandidate za svakog ICE kandidata primljenog sa daleke strane; slično obrnuto za Answer SDP i udaljene ICE kandidate. Sam odgovor SDP formiran je slično Ponudi; razlika je u tome što se ne poziva metoda createOffer, već metoda createAnswer, a prije ove RTCPeerConnection, setRemoteDescription metoda prosljeđuje SDP ponude primljen od pozivatelja.

Dodajmo još jedan video element u HTML:

I globalna varijabla za drugu RTCPeerConnection pod deklaracijom prve:

Varpc2;

Obrada ponude i odgovora SDP

Formiranje SDP-a odgovora je vrlo slično Ponudi. U funkciji povratnog poziva koja se poziva nakon uspješnog formiranja Odgovora, slično kao Ponuda, dat ćemo lokalni opis i proslijediti primljeni SDP odgovora prvom učesniku:

Funkcija pc2_createAnswer_success(desc) ( pc2.setLocalDescription(desc); console.log("pc2_createAnswer_success()", desc.sdp); pc1.setRemoteDescription(desc); )

Funkcija povratnog poziva pozvana u slučaju greške prilikom generiranja odgovora potpuno je slična Ponudi:

Funkcija pc2_createAnswer_error(error) ( console.log("pc2_createAnswer_error():", greška); )

Parametri za generisanje SDP-a odgovora:

Var answerConstraints = ( "obavezno": ( "OfferToReceiveAudio":true, "OfferToReceiveVideo":true ) );

Kada drugi učesnik primi ponudu, kreirajte RTCPeerConnection i formirajte odgovor na isti način kao i ponuda:

Funkcija pc2_receivedOffer(desc) ( console.log("pc2_receiveOffer()", desc); // Kreirajte RTCPeerConnection objekat za drugog učesnika sličan prvom pc2 = new webkitRTCPeerConnection(servers); pc2.onicecandidate = pc2_onicecandi; //Set rukovalac događaja kada je ICE kandidat pc2.onaddstream = pc_onaddstream; // Kada se pojavi stream, povežite ga sa HTML

Da biste prenijeli SDP ponude sa prvog učesnika na drugog, kao dio našeg primjera, dekomentirajte u funkciji pc1 createOffer uspjeh() poziv niz:

Pc2_receivedOffer(desc);

Da biste implementirali obradu ICE kandidata, dekomentirajte u obrađivaču događaja spremnosti ICE kandidata prvog učesnika pc1_onicecandidate() njegov prijenos drugom:

Pc2.addIceCandidate(novi RTCIceCandidate(event.candidate));

Rukovalac događaja spremnosti kandidata za ICE drugog učesnika je sličan prvom:

Funkcija pc2_onicecandidate(event) ( if (event.candidate) ( console.log("pc2_onicecandidate():", event.candidate.candidate); pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

Funkcija povratnog poziva za dodavanje medijskog toka od prvog učesnika:

Funkcija pc2_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo2.src = URL.createObjectURL(event.stream); )

Prekidanje veze

Hajde da dodamo još jedno dugme u HTML

I funkcija za prekid veze

Funkcija btnHangupClick() ( // Onemogući lokalni video iz HTML elemenata

Sačuvajmo ga kao rtctest3.html, stavimo ga na server i otvorimo u pretraživaču. Ovaj primjer implementira dvosmjerni protok medija između dvije RTCPeerConnections unutar iste kartice pretraživača. Za organizaciju razmjene ponuda i odgovora SDP, ICE kandidata između učesnika i drugih informacija putem mreže, bit će potrebno implementirati razmjenu između učesnika korištenjem neke vrste transporta, u našem slučaju web socketa, umjesto direktnog poziva na procedure.

Screen Broadcast

Uz funkciju getUserMedia, također možete snimiti ekran i streamati kao MediaStream navodeći sljedeće parametre:

Var mediaStreamConstraints = ( audio: lažno, video: ( obavezno: ( chromeMediaSource: "screen"), opciono: ) );

Za uspješan pristup ekranu potrebno je ispuniti nekoliko uslova:

  • omogući oznaku snimka ekrana u getUserMedia() u chrome://flags/,chrome://flags/;
  • izvorna datoteka mora biti preuzeta putem HTTPS-a (SSL porijeklo);
  • audio stream se ne smije zahtijevati;
  • više zahtjeva ne bi trebalo postavljati na istoj kartici pretraživača.

Biblioteke za WebRTC

Iako WebRTC još nije završen, već se pojavilo nekoliko biblioteka zasnovanih na njemu. JsSIP je dizajniran za kreiranje softverskih telefona baziranih na pretraživaču koji rade sa SIP prekidačima kao što su Asterisk i Camalio. PeerJS će pojednostaviti kreiranje P2P mreža za razmjenu podataka, a Holla će smanjiti količinu razvoja potrebnu za P2P komunikaciju iz pretraživača.

Node.js i socket.io

Kako bismo organizirali razmjenu SDP i ICE kandidata između dvije RTCPeerConnections preko mreže, koristimo Node.js sa modulom socket.io.

Opisana je instalacija najnovije stabilne verzije Node.js (za Debian/Ubuntu).

$ sudo apt-get install python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs

Opisana je instalacija za druge operativne sisteme

provjerimo:

$ echo "sys=require("util"); sys.puts("Test poruka");" > nodetest1.js $ nodejs nodetest1.js

Koristeći npm (Node Package Manager) instalirajte socket.io i dodatni ekspresni modul:

$ npm install socket.io express

Provjerimo to kreiranjem datoteke nodetest2.js za serversku stranu:

$ nano nodetest2.js var app = require("express")() , server = require("http").createServer(app) , io = require("socket.io").listen(server); server.listen(80); // Ako je port 80 besplatan app.get("/", funkcija (req, res) ( // Prilikom pristupa korijenskoj stranici res.sendfile(__dirname + "/nodetest2.html"); // dajte HTML datoteku ) ) ; io.sockets.on("connection", function (socket) ( // Na vezi socket.emit("server event", (hello: "world" )); // pošalji poruku socket.on("client event", function (data) ( // i deklariramo rukovaoce događajima kada stigne poruka od klijenta console.log(data); )); ));

I nodetest2.html za klijentsku stranu:

$nano nodetest2.html

Pokrenimo server:

$ sudo nodejs nodetest2.js

i otvorite stranicu http://localhost:80 (ako radi lokalno na portu 80) u pretraživaču. Ako sve bude uspješno, u JavaScript konzoli pretraživača vidjet ćemo razmjenu događaja između pretraživača i servera nakon povezivanja.

Razmjena informacija između RTCPeerConnection preko web utičnica

Na strani klijenta

Sačuvajmo naš glavni primjer (rtcdemo3.html) pod novim imenom rtcdemo4.html. Uključite biblioteku socket.io u element:

I na početku JavaScript skripte - veza web socketa:

var socket = io.connect("http://localhost");

Zamijenimo direktan poziv funkcijama drugog sudionika tako što ćemo mu poslati poruku preko web utičnica:

Funkcija createOffer_success(desc) ( ... // pc2_receivedOffer(desc); socket.emit("offer", desc); ... ) funkcija pc2_createAnswer_success(desc) ( ... // pc1.setRemoteDescription(desc); socket .emit("odgovor", desc); ) funkcija pc1_onicecandidate(event) ( ... // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice1", event.candidate); .. . ) funkcija pc2_onicecandidate(event) ( ... // pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice2", event.candidate); ... )

U funkciji hangup(), umjesto direktnog pozivanja funkcija drugog sudionika, poslat ćemo poruku preko web utičnica:

Funkcija btnHangupClick() ( ... // remoteVideo2.src = ""; pc2.close(); pc2 = null; socket.emit("hangup", ()); )

I dodajte rukovaoce primanja poruka:

Socket.on("ponuda", funkcija (podaci) ( console.log("socket.on("offer"):", podaci); pc2_receivedOffer(data); )); socket.on("odgovor", funkcija (podaci) (e console.log("socket.on("odgovor"):", podaci); pc1.setRemoteDescription(novi RTCSessionDescription(podaci)); )); socket.on("ice1", funkcija (podaci) ( console.log("socket.on("ice1"):", podaci); pc2.addIceCandidate(novi RTCIceCandidate(data)); )); socket.on("ice2", funkcija (podaci) ( console.log("socket.on("ice2"):", podaci); pc1.addIceCandidate(novi RTCIceCandidate(data)); )); socket.on("hangup", funkcija (podaci) ( console.log("socket.on("hangup")):", data); remoteVideo2.src = ""; pc2.close(); pc2 = null; ) );

Serverski dio

Na strani servera sačuvajte datoteku nodetest2 pod novim imenom rtctest4.js i unutar funkcije io.sockets.on("connection", function (socket) ( ... ) dodajte primanje i slanje poruka klijenta:

Socket.on("offer", function (data) ( // Prilikom primanja poruke "ponuda", // pošto u ovom primjeru postoji samo jedna klijentska veza, // pošaljite poruku nazad kroz isti socket.emit( "offer" , data); // Ako je bilo potrebno proslijediti poruku na svim konekcijama // osim na pošiljatelja: // socket.broadcast.emit("offer", data); )); socket.on("odgovor", funkcija (podaci) ( socket.emit("odgovor", podaci); )); socket.on("ice1", funkcija (podaci) ( socket.emit("ice1", podaci); )); socket.on("ice2", funkcija (podaci) ( socket.emit("ice2", podaci); )); socket.on("prekid", funkcija (podaci) ( socket.emit("prekid", podaci); ));

Osim toga, promijenite naziv HTML datoteke:

// res.sendfile(__dirname + "/nodetest2.html"); // Pošaljite HTML datoteku res.sendfile(__dirname + "/rtctest4.html");

Početak servera:

$ sudo nodejs nodetest2.js

Uprkos činjenici da se kod oba klijenta izvršava unutar iste kartice pretraživača, sva interakcija između učesnika u našem primeru se u potpunosti odvija preko mreže i više nije teško „širiti“ učesnike. Međutim, ono što smo uradili bilo je vrlo jednostavno - ove tehnologije su dobre zbog svoje lakoće upotrebe. Iako ponekad varljivo. Posebno, ne zaboravimo da bez STUN/TURN servera, naš primjer neće moći raditi u prisustvu translacije adresa i firewall-a.

Zaključak

Dobijeni primjer je vrlo uvjetovan, ali ako malo univerzaliziramo rukovaoce događajima tako da se ne razlikuju između pozivajuće i pozvane strane, umjesto dva objekta pc1 i pc2, napravite niz RTCPeerConnection i implementirajte dinamičko kreiranje i brisanje elemenata

Može se pretpostaviti da će vrlo brzo, zahvaljujući WebRTC-u, doći do revolucije ne samo u našem razumijevanju glasovnih i video komunikacija, već i u tome kako percipiramo Internet u cjelini. WebRTC je pozicioniran ne samo kao tehnologija poziva između pretraživača, već i kao komunikacijska tehnologija u realnom vremenu. Video komunikacija, koju smo analizirali, samo je mali dio mogućih opcija za njeno korištenje. Već postoje primjeri dijeljenja ekrana (screen sharing) i saradnje, pa čak i P2P mreže za isporuku sadržaja zasnovane na pretraživaču koristeći RTCDataChannel.

WebRTC (Web Real Time Communications) je standard koji opisuje prijenos streaming audio podataka, video podataka i sadržaja iz pretraživača u pretraživač u realnom vremenu bez instaliranja dodataka ili drugih ekstenzija. Standard vam omogućava da pretvorite pretraživač u terminal za video konferencije, samo otvorite web stranicu da započnete komunikaciju.

Šta je WebRTC?

U ovom članku ćemo pokriti sve što treba znati o WebRTC tehnologiji za prosječnog korisnika. Hajde da razmotrimo prednosti i nedostatke projekta, otkrijemo neke tajne, kažemo vam kako funkcioniše, gde i za šta se koristi WebRTC.

Šta trebate znati o WebRTC-u?

Evolucija video standarda i tehnologija

Sergej Yutsaitis, Cisco, Video+Conference 2016

Kako radi WebRTC

Na strani klijenta

  • Korisnik otvara stranicu koja sadrži HTML5 tag
  • Pretraživač traži pristup web kameri i mikrofonu korisnika.
  • JavaScript kod na korisničkoj stranici kontroliše parametre veze (IP adrese i portove WebRTC servera ili drugih WebRTC klijenata) kako bi se zaobišlo NAT i zaštitni zid.
  • Prilikom primanja informacija o sagovorniku ili o streamu s konferencijom pomiješanom na serveru, pretraživač počinje pregovarati o korištenim audio i video kodecima.
  • Počinje proces kodiranja i striminga podataka između WebRTC klijenata (u našem slučaju između pretraživača i servera).

Na strani WebRTC servera

Za razmjenu podataka između dva učesnika nije potreban video server, ali ako želite spojiti više učesnika u jednu konferenciju, potreban je server.



Video server će primati medijski promet iz različitih izvora, pretvarati ga i slati korisnicima koji koriste WebRTC kao terminal.

WebRTC server će također primati medijski promet od WebRTC kolega i proslijeđivati ​​ga učesnicima konferencije koristeći desktop ili mobilne aplikacije, ako ih ima.

Prednosti standarda

  • Nije potrebna instalacija softvera.
  • Vrlo visok kvalitet komunikacije zahvaljujući:
    • Upotreba modernih video (VP8, H.264) i audio kodeka (Opus).
    • Automatsko prilagođavanje kvalitete streama uvjetima veze.
    • Ugrađeno poništavanje eha i buke.
    • Automatska kontrola nivoa mikrofona učesnika (AGC).
  • Visok nivo sigurnosti: sve veze su sigurne i šifrovane prema TLS i SRTP protokolima.
  • Postoji ugrađeni mehanizam za snimanje sadržaja, kao što je desktop.
  • Mogućnost implementacije bilo kojeg kontrolnog interfejsa zasnovanog na HTML5 i JavaScript-u.
  • Mogućnost integracije interfejsa sa bilo kojim pozadinskim sistemima koristeći WebSockets.
  • Projekat otvorenog koda - možete ga ugraditi u svoj proizvod ili uslugu.
  • Prava višeplatformska: ista WebRTC aplikacija će raditi podjednako dobro na bilo kom operativnom sistemu, desktop ili mobilnom uređaju, pod uslovom da pretraživač podržava WebRTC. Ovo štedi mnogo resursa za razvoj softvera.

Nedostaci standarda

  • Za organizaciju grupnih audio i video konferencija potreban je server za video konferencije koji bi miksao video i audio od učesnika, jer pretraživač ne zna kako da sinhronizuje više dolaznih tokova jedan s drugim.
  • Sva WebRTC rješenja su međusobno nekompatibilna, jer standard opisuje samo metode za prijenos videa i zvuka, ostavljajući implementaciju metoda za obraćanje pretplatnicima, praćenje njihove dostupnosti, razmjenu poruka i datoteka, zakazivanje i druge stvari za dobavljača.
  • Drugim riječima, nećete moći pozvati iz WebRTC aplikacije jednog programera u WebRTC aplikaciju drugog programera.
  • Grupno konferencijsko miksovanje zahteva dosta računarskih resursa, tako da ova vrsta video komunikacije zahteva kupovinu plaćene pretplate ili ulaganje u njenu infrastrukturu, gde je za svaku konferenciju potrebno 1 fizičko jezgro modernog procesora.

WebRTC tajne: kako dobavljači imaju koristi od disruptivne web tehnologije


Tzachi Levent-Levi, Bloggeek.me, Video+Conference 2015

WebRTC za tržište video konferencija

Povećanje broja terminala za video konferencije

WebRTC tehnologija je imala snažan uticaj na razvoj tržišta video konferencija. Nakon objavljivanja prvih pretraživača s podrškom za WebRTC 2013. godine, potencijalni broj terminala za video konferencije širom svijeta odmah se povećao za milijardu uređaja. Zapravo, svaki pretraživač je postao terminal za video konferencije koji nije inferioran u odnosu na svoje hardverske kolege u smislu kvaliteta komunikacije.

Upotreba u specijalizovanim rešenjima

Upotreba različitih JavaScript biblioteka i API-ja cloud servisa sa podrškom za WebRTC olakšava dodavanje video podrške bilo kojim web projektima. U prošlosti je prijenos podataka u realnom vremenu zahtijevao od programera da nauče kako funkcionišu protokoli i koriste rad drugih kompanija, što je najčešće zahtijevalo dodatno licenciranje, što je povećavalo troškove. WebRTC se već aktivno koristi u uslugama kao što su „Poziv sa stranice“, „Online chat podrška“ itd.

Bivši korisnici Skype-a za Linux

Microsoft je 2014. godine najavio prestanak podrške za projekat Skype za Linux, što je izazvalo veliku uznemirenost među IT profesionalcima. WebRTC tehnologija nije vezana za operativni sistem, već je implementirana na nivou pretraživača, tj. Korisnici Linuxa će moći da vide proizvode i usluge zasnovane na WebRTC-u kao potpunu zamenu za Skype.

Konkurencija sa Flash-om

WebRTC i HTML5 bili su smrtni udarac za Flash tehnologiju, koja je već prolazila kroz svoje daleko od najboljih godina. Od 2017. godine vodeći pretraživači su zvanično prestali da podržavaju Flash i tehnologija je konačno nestala sa tržišta. Ali morate odati priznanje Flashu, jer je on stvorio tržište web konferencija i ponudio tehničke mogućnosti za živu komunikaciju u pretraživačima.

WebRTC video prezentacije

Dmitrij Odintsov, TrueConf, Video+Conference oktobar 2017

Kodeci u WebRTC-u

Audio kodeci

Za kompresiju audio saobraćaja u WebRTC-u koriste se kodeci Opus i G.711.

G.711- najstariji glasovni kodek sa visokim bitrate-om (64 kbps), koji se najčešće koristi u tradicionalnim telefonskim sistemima. Glavna prednost je minimalno računarsko opterećenje zbog upotrebe lakih algoritama kompresije. Kodek ima nizak nivo kompresije glasovnih signala i ne unosi dodatno kašnjenje zvuka tokom komunikacije između korisnika.

G.711 podržava veliki broj uređaja. Sistemi koji koriste ovaj kodek su lakši za upotrebu od onih zasnovanih na drugim audio kodecima (G.723, G.726, G.728, itd.). Što se tiče kvaliteta, G.711 je dobio ocenu 4,2 na MOS testiranju (ocena 4-5 je najveća i znači dobar kvalitet, sličan kvalitetu govornog saobraćaja u ISDN-u pa čak i viši).

Opus je kodek s niskom latencijom kodiranja (od 2,5 ms do 60 ms), podrškom za promjenjivu brzinu prijenosa i visokom kompresijom, što je idealno za audio streaming preko mreža s promjenjivim propusnim opsegom. Opus je hibridno rješenje koje kombinuje najbolje karakteristike kodeka SILK (kompresija glasa, eliminacija izobličenja ljudskog govora) i CELT (kodiranje audio podataka). Kodek je besplatno dostupan, programeri koji ga koriste ne moraju plaćati autorske naknade vlasnicima autorskih prava. U poređenju sa drugim audio kodecima, Opus sigurno pobjeđuje na mnogo načina. Zamračio je prilično popularne kodeke niske bitrate kao što su MP3, Vorbis, AAC LC. Opus vraća "sliku" zvuka bližu originalu nego AMR-WB i Speex. Ovaj kodek je budućnost, zbog čega su ga kreatori WebRTC tehnologije uvrstili u obavezni opseg podržanih audio standarda.

Video kodeci

Problemi sa odabirom video kodeka za WebRTC uzeli su programere nekoliko godina, da bi na kraju odlučili da koriste H.264 i VP8. Gotovo svi moderni pretraživači podržavaju oba kodeka. Serveri za video konferencije trebaju podržavati samo jedan za rad sa WebRTC-om.

VP8 je besplatni video kodek sa otvorenom licencom, sa velikom brzinom dekodiranja video toka i povećanom otpornošću na gubitak kadrova. Kodek je univerzalan, lako ga je implementirati u hardverske platforme, pa ga programeri video konferencijskih sistema često koriste u svojim proizvodima.

Plaćeni video kodek H.264 postao poznat mnogo ranije od njegovog brata. Ovo je kodek sa visokim stepenom kompresije video toka uz održavanje visokog kvaliteta videa. Velika rasprostranjenost ovog kodeka među hardverskim video konferencijskim sistemima ukazuje na njegovu upotrebu u WebRTC standardu.

Google i Mozilla aktivno promovišu VP8 kodek, dok Microsoft, Apple i Cisco aktivno promovišu H.264 (kako bi osigurali kompatibilnost sa tradicionalnim sistemima za video konferencije). I tu nastaje vrlo veliki problem za programere WebRTC rješenja zasnovanih na oblaku, jer ako svi učesnici konferencije koriste isti pretraživač, onda je dovoljno konferenciju jednom pomiješati sa jednim kodekom, a ako su pretraživači različiti i među njima postoji Safari / Edge, tada će konferencija morati biti kodirana dva puta različitim kodecima, što će udvostručiti sistemske zahtjeve za medijski server i, kao rezultat, cijenu pretplate na WebRTC usluge.

WebRTC API

WebRTC tehnologija je zasnovana na tri glavna API-ja:

  • (odgovoran za web pretraživač da prima audio i video signale sa kamera ili radne površine korisnika).
  • RTCPeerConnection(odgovoran za vezu između pretraživača za “razmjenu” medijskih podataka primljenih sa kamere, mikrofona i desktopa. Također, “dužnosti” ovog API-ja uključuju obradu signala (čišćenje od strane buke, podešavanje jačine mikrofona) i kontrolu preko audio i video kodeka koji se koriste) .
  • RTC kanal podataka(omogućava dvosmjerni prijenos podataka preko uspostavljene veze).

Prije pristupa korisnikovom mikrofonu i kameri, pretraživač traži ovu dozvolu. U Google Chromeu možete unaprijed konfigurirati pristup u odjeljku "Postavke", u Operi i Firefoxu izbor uređaja se vrši direktno u trenutku pristupa, sa padajuće liste. Zahtjev za dozvolu će se uvijek pojaviti kada koristite HTTP protokol i jednom ako koristite HTTPS:


RTCPeerConnection. Svaki pretraživač koji učestvuje u WebRTC konferenciji mora imati pristup ovom objektu. Zahvaljujući upotrebi RTCPeerConnection, medijski podaci iz jednog pretraživača u drugi mogu čak proći kroz NAT i firewall. Za uspješan prijenos medijskih tokova, učesnici moraju razmijeniti sljedeće podatke koristeći transport kao što su web utičnice:

  • učesnik-inicijator šalje drugom učesniku Ponuda-SDP (struktura podataka, sa karakteristikama medijskog toka koji će prenositi);
  • drugi učesnik generiše “odgovor” - Odgovor-SDP i šalje ga inicijatoru;
  • zatim se organizuje razmena ICE kandidata između učesnika, ako ih ima (ako su učesnici iza NAT-a ili firewall-a).

Nakon uspješnog završetka ove razmjene između učesnika, direktno se organizira prijenos medijskih tokova (audio i video).

RTC kanal podataka. Podrška za protokol Data Channel pojavila se u pretraživačima relativno nedavno, tako da se ovaj API može uzeti u obzir samo u slučajevima kada se WebRTC koristi u pretraživačima Mozilla Firefox 22+ i Google Chrome 26+. Uz to, učesnici mogu razmjenjivati ​​tekstualne poruke u pretraživaču.

WebRTC veza

Podržani desktop pretraživači

  • Google Chrome (17+) i svi pretraživači bazirani na Chromium motoru;
  • Mozilla Firefox (18+);
  • Opera (12+);
  • Safari (11+);

Podržani mobilni pretraživači za Android

  • Google Chrome (28+);
  • Mozilla Firefox (24+);
  • Opera Mobile (12+);
  • Safari (11+).

WebRTC, Microsoft i Internet Explorer

Dugo je Microsoft ćutao o podršci za WebRTC u Internet Exploreru i njegovom novom Edge pretraživaču. Momci iz Redmonda baš i ne vole da daju tehnologiju u ruke korisnika koju ne kontrolišu, takva je politika. Ali postepeno su stvari krenule s početka, jer. Više nije bilo moguće ignorisati WebRTC, a najavljen je ORTC projekat, izveden iz WebRTC standarda.

Kako kažu programeri, ORTC je proširenje WebRTC standarda sa poboljšanim skupom API-ja baziranih na JavaScriptu i HTML5, što, prevedeno na običan jezik, znači da će sve biti isto, samo će Microsoft, a ne Google, kontrolirati standard i njegov razvoj. Skup kodeka je proširen podrškom za H.264 i neke audio kodeke serije G.7XX koji se koriste u telefoniji i hardverskim video konferencijskim sistemima. Možda će biti ugrađena podrška za RDP (za prijenos sadržaja) i razmjenu poruka. Inače, korisnici Internet Explorera nemaju sreće, ORTC podrška će biti samo u Edge-u. I, naravno, takav skup protokola i kodeka se s malo krvi uklapa u Skype for Business, što otvara još više poslovnih aplikacija za WebRTC.

WebRTC je API koji pruža pretraživač koji vam omogućava da organizujete P2P vezu i prenosite podatke direktno između pretraživača. Na internetu postoji dosta tutorijala o tome kako napisati svoj vlastiti video chat koristeći WebRTC. Na primjer, evo članka o Habréu. Međutim, svi su ograničeni na povezivanje dva klijenta. U ovom članku pokušat ću govoriti o tome kako organizirati vezu i razmjenu poruka između tri ili više korisnika koristeći WebRTC.

Interfejs RTCPeerConnection je peer-to-peer veza između dva pretraživača. Da bismo povezali tri ili više korisnika, morat ćemo organizirati mesh mrežu (mrežu u kojoj je svaki čvor povezan sa svim ostalim čvorovima).
Koristićemo sledeću šemu:

  1. Prilikom otvaranja stranice provjeravamo prisustvo ID-a sobe lokacija.haš
  2. Ako ID sobe nije naveden, generirajte novi
  3. Šaljemo signalnom serveru "poruku da želimo da se pridružimo navedenoj prostoriji
  4. Signalni server šalje obavještenje o novom korisniku drugim klijentima u ovoj prostoriji
  5. Klijenti koji su već u sobi šalju SDP ponudu pridošlicu
  6. Pridošlica se odaziva na ponudu "s

0. Server za signalizaciju

Kao što znate, iako WebRTC pruža mogućnost P2P veze između pretraživača, ipak je potreban dodatni transport za razmjenu servisnih poruka. U ovom primjeru, transport je WebSocket server napisan u Node.JS koristeći socket.io:

var socket_io = require("socket.io"); module.exports = funkcija (server) ( var users = (); var io = socket_io(server); io.on("connection", function(socket) ( // Želim da se novi korisnik pridruži prostoriji socket.on( "room ", function(message) ( var json = JSON. parse(message); // Dodajte utičnicu na listu korisnika user = socket; if (socket.room !== undefined) ( // Ako je utičnica već u nekoj prostoriji, ostavite je socket.leave(socket.room); ) // Unesite traženu sobu socket.room = json.room; socket.join(socket.room); socket.user_id = json.id; // Pošaljite drugim klijentima ova soba ima poruku o pridruživanju novom učesniku socket.broadcast.to(socket.room).emit("new", json.id); )); // Poruka vezana za WebRTC (SDP ponuda, SDP odgovor ili ICE kandidat) socket.on("webrtc", function(message) ( var json = JSON.parse(message); if (json.to !== undefined && users !== undefined) ( // Ako poruka ima primaoca i ovog primaoca poznatog serveru, pošaljite poruku samo njemu... users.emit("webrtc", poruka); ) else ( // ...inače smatrajte poruku emitovanom socket.broadcast.to(socket.room).emit("webrtc", message); ) )); // Netko je prekinuo vezu socket.on("disconnect", function() ( // Kada se klijent prekine, obavijesti druge socket.broadcast.to(socket.room).emit("leave", socket.user_id); delete users; )); )); );

1. index.html

Izvorni kod za samu stranicu je prilično jednostavan. Namjerno nisam obraćao pažnju na izgled i ostale ljepote, jer ovaj članak nije o tome. Ako neko želi da je ulepša, to neće biti teško.

WebRTC Chat Demo

spojen na 0 vršnjaci

2.main.js

2.0. Dobivanje veza do elemenata stranice i WebRTC interfejsa
var chatlog = document.getElementById("chatlog"); var message = document.getElementById("message"); var connection_num = document.getElementById("connection_num"); var room_link = document.getElementById("room_link");

I dalje moramo da koristimo prefikse pretraživača za pristup WebRTC interfejsima.

Var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription; var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

2.1. Određivanje ID sobe

Ovdje nam je potrebna funkcija za generiranje jedinstvene sobe i korisničkog ID-a. U tu svrhu ćemo koristiti UUID.

Funkcija uuid () ( var s4 = function() ( return Math.floor(Math.random() * 0x10000).toString(16); ); return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4(); )

Sada pokušajmo da izvučemo ID sobe iz adrese. Ako ovo nije postavljeno, generirat ćemo novi. Na stranici ćemo prikazati link do trenutne sobe, a istovremeno ćemo generirati identifikator za trenutnog korisnika.

VarROOM = lokacija.hash.substr(1); if (!ROOM) ( ROOM = uuid(); ) room_link.innerHTML = "Veza do sobe"; varME = uuid();

2.2. web socket

Odmah po otvaranju stranice spojit ćemo se na naš signalni server, poslati zahtjev za ulazak u sobu i odrediti rukovaoce porukama.

// Navodimo da kada se poruka zatvori, moramo poslati obavijest serveru o ovome var socket = io.connect("", ("sync disconnect on unload": true)); socket.on("webrtc", socketReceived); socket.on("novo", socketNewPeer); // Odmah pošaljite zahtjev za ulazak u sobu socket.emit("room", JSON.stringify((id: ME, room: ROOM))); // Pomoćna funkcija za slanje adresnih poruka povezanih s WebRTC funkcijom sendViaSocket(type, message, to) ( socket.emit("webrtc", JSON.stringify((id: ME, to: to, type: type, data: message ) )); )

2.3. Postavke ravnopravne veze

Većina ISP-a omogućava internet konekciju preko NAT-a. Zbog toga direktna veza ne postaje tako trivijalna. Kada kreiramo konekciju, potrebno je da navedemo listu STUN i TURN servera koje će pretraživač pokušati da koristi da zaobiđe NAT. Također ćemo navesti nekoliko dodatnih opcija za povezivanje.

Var server = ( iceServers: [ (url: "stun:23.21.150.121"), (url: "stun:stun.l.google.com:19302"), (url: "turn:numb.viagenie.ca", vjerodajnica: "vaša lozinka ide ovdje", korisničko ime: " [email protected]") ] ); var options = ( opcionalno: [ (DtlsSrtpKeyAgreement: true), // potrebno za vezu između Chromea i Firefoxa (RtpDataChannels: true) // potrebno u Firefoxu za korištenje DataChannels API-ja ] )

2.4. Povezivanje novog korisnika

Kada se u sobu doda novi peer, server nam šalje poruku novo. Prema gore navedenim rukovateljima poruka, funkcija će biti pozvana socketNewPeer.

var peers = (); funkcija socketNewPeer(data) ( peers = (candidateCache: ); // Kreirajte novu vezu var pc = new PeerConnection(server, options); // Inicijalizirajte initConnection(pc, data, "offer"); // Spremite peer na listi peers peers.connection = pc; // Kreirajte DataChannel kroz koji će se poruke razmjenjivati ​​var channel = pc.createDataChannel("mychannel", ()); channel.owner = data; peers.channel = channel; // Postavite rukovaoce događajima bindEvents(channel); // Kreirajte SDP ponudu pc.createOffer(function(offer) ( pc.setLocalDescription(offer); )); ) function initConnection(pc, id, sdpType) ( pc.onicecandidate = function ( event) ( if (event.candidate) ( // Kada se pronađe novi ICE kandidat, dodajte ga na listu za dalje slanje peers.candidateCache.push(event.candidate); ) else ( // Kada je otkrivanje kandidata završeno, obrađivač će biti ponovo pozvan, ali bez kandidata // U ovom slučaju prvo šaljemo vršnjaku SDP ponudu, ili SDP-ov odgovor (u zavisnosti od parametra funkcije)... sendViaSocket(sdpType, pc.localDescription, id); // ...a zatim svi prethodno pronađeni ICE kandidati za (var i = 0; i< peers.candidateCache.length; i++) { sendViaSocket("candidate", peers.candidateCache[i], id); } } } pc.oniceconnectionstatechange = function (event) { if (pc.iceConnectionState == "disconnected") { connection_num.innerText = parseInt(connection_num.innerText) - 1; delete peers; } } } function bindEvents (channel) { channel.onopen = function () { connection_num.innerText = parseInt(connection_num.innerText) + 1; }; channel.onmessage = function (e) { chatlog.innerHTML += "

Peer kaže: " + e.data + "
"; }; }

2.5. Ponuda SDP-a, odgovor SDP-a, kandidat ICE

Kada se primi jedna od ovih poruka, pozivamo odgovarajući rukovalac porukama.

Funkcija socketReceived(data) ( var json = JSON.parse(data); switch (json.type) ( case "candidate": remoteCandidateReceived(json.id, json.data); break; case "offer": remoteOfferReceived(json. id, json.data); prekid; slučaj "odgovor": remoteAnswerReceived(json.id, json.data); break; ) )

2.5.0 SDP ponuda
function remoteOfferReceived(id, data) (createConnection(id); var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data)); pc.createAnswer(function(answer) (pc.setLocalDescription(odgovor); )); ) funkcija createConnection(id) ( if (peers === undefined) ( peers = (candidateCache: ); var pc = new PeerConnection(server, opcije); initConnection(pc, id, "odgovor"); peers.connection = pc ; pc.ondatachannel = funkcija(e) ( peers.channel = e.channel; peers.channel.owner = id; bindEvents(peers.channel); ) ) )
2.5.1 SDP odgovor
funkcija remoteAnswerReceived(id, data) (var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data)); )
2.5.2 ICE kandidat
funkcija remoteCandidateReceived(id, data) (createConnection(id); var pc = peers.connection; pc.addIceCandidate(new IceCandidate(data)); )
2.6. Slanje poruke

Pritiskom na dugme poslati funkcija se poziva pošalji poruku. Sve što radi je da prođe kroz listu kolega i pokuša da pošalje navedenu poruku svima.