WebRTC. Videokonferens i webbläsaren


WebRTC (Web Real-Time Communications) är en teknik som tillåter webbapplikationer och webbplatser att fånga och selektivt överföra ljud- och/eller videomedieströmmar, samt utbyta godtycklig data mellan webbläsare, utan att nödvändigtvis använda mellanhänder. Den uppsättning standarder som WebRTC-tekniken inkluderar låter dig utbyta data och genomföra peer-to-peer-telekonferenser utan att användaren behöver installera plugins eller någon annan programvara från tredje part.

WebRTC består av flera sammankopplade applikationsprogrammeringsgränssnitt (API) och protokoll som fungerar tillsammans. Dokumentationen du hittar här hjälper dig att förstå grunderna i WebRTC, hur du konfigurerar och använder en anslutning för data- och mediaströmning och mycket mer.

Kompatibilitet

Eftersom WebRTC-implementeringen fortfarande är i sin linda och varje webbläsare har WebRTC-funktioner, rekommenderar vi starkt att du använder Googles Adapter.js polyfill-bibliotek innan du börjar arbeta med din kod.

Adapter.js använder wedges och polyfills för att sömlöst överbrygga skillnader i WebRTC-implementationer mellan de sammanhang som stöder det. Adapter.js hanterar även leverantörsprefix och andra egenskapsnamnskillnader, vilket gör det lättare att utveckla på WebRTC med de mest kompatibla resultaten. Biblioteket finns även som ett NPM-paket.

Ta en titt om du vill utforska Adapter.js-biblioteket ytterligare.

WebRTC-koncept och användning

WebRTC är mångsidigt och ger tillsammans med , kraftfulla multimediafunktioner för webben, inklusive stöd för ljud- och videokonferenser, fildelning, skärmdumpning, identitetshantering och interoperabilitet med äldre telefonsystem, inklusive stöd för DTMF-tonuppringning. Anslutningar mellan noder kan skapas utan användning av speciella drivrutiner eller plugins, och ofta utan mellanliggande tjänster.

Kopplingen mellan två noder representeras som ett RTCPeerConnection-gränssnittsobjekt. När en anslutning har upprättats och öppnats, med hjälp av objektet RTCPeerConnection, kan mediaströmmar (MediaStreams) och/eller datakanaler (RTCDataChannels) läggas till anslutningen.

Medieströmmar kan bestå av valfritt antal spår (spår) med medieinformation. Dessa spår representeras av MediaStreamTrack-gränssnittsobjekt och kan innehålla en eller flera typer av mediadata, inklusive ljud, video, text (som undertexter eller kapiteltitlar). De flesta strömmar består av minst ett ljudspår (ett ljudspår), eller videospår, och kan skickas och tas emot som strömmar (realtidsmedia) eller sparas i en fil.

Du kan också använda en anslutning mellan två noder för att utbyta godtycklig data med RTCDataChannel-gränssnittsobjektet, som kan användas för att överföra tjänsteinformation, aktiemarknadsdata, spelstatuspaket, filöverföring eller privata datakanaler.

mer information och länkar till relevanta guider och handledningar behövs

WebRTC-gränssnitt

Eftersom WebRTC tillhandahåller gränssnitt som fungerar tillsammans för att utföra olika uppgifter har vi delat in dem i kategorier. Se sidofältsindexet för snabb navigering.

Anslutningskonfiguration och hantering

Dessa gränssnitt används för att konfigurera, öppna och hantera WebRTC-anslutningar. De representerar enskiktiga mediaanslutningar, datakanaler och gränssnitt som används för att utbyta information om kapaciteten hos varje nod för att välja den bästa konfigurationen för att upprätta en tvåvägs multimediaanslutning.

RTCPeerConnection Representerar en WebRTC-anslutning mellan en lokal dator och en fjärrnod. Används för att hantera framgångsrik dataöverföring mellan två noder. RTCSessionDescription Representerar sessionsparametrarna. Varje RTCSessionDescription innehåller beskrivningar av typen , som anger vilken del (erbjudande/svar) av förhandlingsprocessen den beskriver, och en SDP-beskrivning för sessionen. RTCIceCandidate Representerar Internet Connection Establishment (ICE)-serverkandidaten för att upprätta en RTCPeerConnection-anslutning. RTCIceTransport representerar information om Internet Connectivity Facility (ICE). RTCPeerConnectionIceEvent Representerar händelser som inträffar på ICE-kandidater, vanligtvis RTCPeerConnection . En typ skickas till detta händelseobjekt: icecandidate. RTCRtpSender Styr strömning och överföring av data genom ett objekt av typen MediaStreamTrack för ett objekt av typen RTCPeerConnection. RTCRtpReceiver Styr mottagning och avkodning av data genom ett objekt av typen MediaStreamTrack för ett objekt av typen RTCPeerConnection. RTCTrackEvent Indikerar att ett nytt inkommande MediaStreamTrack-objekt har skapats och ett RTCRtpReceiver-objekt har lagts till i RTCPeerConnection-objektet. RTCCertificate Representerar ett certifikat som använder RTCPeerConnection-objektet. RTCDataChannel Representerar en dubbelriktad datakanal mellan två anslutningsnoder. RTCDataChannelEvent Representerar händelser som uppstår när ett objekt av typen RTCDataChannel kopplas till ett objekt av typen RTCPeerConnection datachannel. RTCDTMFSender Styr kodningen och överföringen av dual-tone multi-frequency (DTMF) signalering för ett objekt av typen RTCPeerConnection . RTCDTMFToneChangeEvent Indikerar en inkommande Dual Tone Multi Frequency (DTMF) tonändringshändelse. Denna händelse bubblar inte (om inget annat anges) och kan inte avbrytas (om inget annat anges). RTCStatsReport rapporterar asynkront status för det passerade objektet av typen MediaStreamTrack. RTCIdentityProviderRegistrar Registrerar en identitetsleverantör (idP). RTCIdentityProvider Aktiverar webbläsarens förmåga att begära att skapa eller verifiera en identitetsdeklaration. RTCIdentityAssertion Representerar fjärrnodidentifieraren för den aktuella anslutningen. Om noden ännu inte har installerats och bekräftats kommer gränssnittsreferensen att returnera null . Förändras inte efter installation. RTCIdentityEvent Representerar ett deklarationshändelseobjekt för identitetsleverantör (idP). Händelse för ett objekt av typen RTCPeerConnection. En typ skickas till denna identitetsresultathändelse. RTCIdentityErrorEvent Representerar ett felhändelseobjekt associerat med en identitetsleverantör (idP). Händelse för ett objekt av typen RTCPeerConnection. Två typer av fel skickas till denna händelse: idpassertionerror och idpvalidationerror. Guider WebRTC-arkitekturöversikt Under API:t, som utvecklare använder för att skapa och använda WebRTC, ligger en uppsättning nätverksprotokoll och anslutningsstandarder. Denna recension är ett exempel på dessa standarder. WebRTC låter dig organisera en anslutning i ett nod-till-nod-läge för att överföra godtyckliga data, ljud, videoströmmar eller någon kombination av dem i webbläsaren. I den här artikeln tar vi en titt på livet för en WebRTC-session, och börjar med att anslutningen upprättas och går hela vägen tills den avslutas när den inte längre behövs. WebRTC API-översikt WebRTC består av flera inbördes relaterade applikationsprogrammeringsgränssnitt (API) och protokoll som samverkar för att stödja utbyte av data och mediaströmmar mellan två eller flera noder. Den här artikeln ger en kort översikt över var och en av dessa API:er och vilket syfte de tjänar. WebRTC Basics Den här artikeln går igenom hur du skapar en RTC-applikation för flera webbläsare. I slutet av den här artikeln bör du ha en fungerande punkt-till-punkt data- och mediakanal. WebRTC-protokoll Den här artikeln introducerar protokollen som kompletterar WebRTC API. Den här guiden beskriver hur du kan använda en nod-till-nod-anslutning och länkad

Inledning. P2P-videochatt baserad på WebRTC är ett alternativ till Skype och andra kommunikationsmedel. Huvudelementen i p2p-videochatt baserad på WebRTC är en webbläsare och en kontaktserver. P2P-videochatt är peer-to-peer-videochatt där servern inte deltar i överföringen av informationsflöden. Information överförs direkt mellan användarnas webbläsare (peers) utan några ytterligare program. Förutom webbläsare använder p2p-videochatt kontaktservrar, som är utformade för att registrera användare, lagra data om dem och säkerställa växling mellan användare. Webbläsare som stöder de senaste WebRTC- och HTML5-teknikerna ger omedelbar textmeddelanden och filöverföring, såväl som röst- och videokommunikation över IP-nätverk.

Så, chattar, webbchatt, röst- och videochatt i ett webbgränssnitt, IMS, VoIP är tjänster som tillhandahåller onlinekommunikation genom sammansatta paketförmedlade nätverk. Som regel kräver kommunikationstjänster antingen installation av klientapplikationer på användarenheter (PC, smartphones, etc.) eller installation av plugins och tillägg i webbläsare. Tjänsterna har sina egna kommunikationsnätverk, varav de flesta är byggda på en klient-server-arkitektur.

Kommunikationstjänster är andra applikationer än IMS, där röst-, video-, data- och textkanalerna inte är integrerade. I nätverken för varje tjänst, . Det bör noteras att dessa applikationer inte samtidigt kan fungera i flera kommunikationsnätverk, d.v.s. Applikationer kan vanligtvis inte kommunicera med varandra, vilket kräver att en separat applikation installeras för varje kommunikationsnätverk.

Problemet med att integrera kommunikationstjänster i realtid (chatt, telefoni, videokonferenser), d.v.s. integration av röst-, video-, datakanaler och åtkomst till dem med en applikation (webbläsare) kan lösas i peer-to-peer eller p2p videochatt (peer-to-peer, point-to-point) baserat på WebRTC-protokollet. I huvudsak blir en webbläsare som stöder WebRTC ett enda gränssnitt för alla användarenheter (datorer, smartphones, iPads, IP-telefoner, mobiltelefoner, etc.) som fungerar med kommunikationstjänster.

Det är WebRTC som säkerställer implementeringen i webbläsaren av all teknik som tillhandahåller realtidskommunikation. Kärnan i p2p-videochatt är att multimedia och textdata överförs direkt mellan användarnas webbläsare (fjärrpeering) utan deltagande av en server eller ytterligare program. Således ger webbläsare inte bara tillgång till nästan alla Internetinformationsresurser som lagras på servrar, utan blir också ett sätt att få tillgång till alla realtidskommunikationstjänster och e-posttjänster (röstbrevlåda, e-post, SMS, etc.)

Servrar (kontaktservrar) för p2p-videochatt är endast avsedda för att registrera användare, lagra data om användare och upprätta en anslutning (växling) mellan användarnas webbläsare. De första p2p-videochattarna implementerades med hjälp av flashteknik. Flash p2p videochatt används till exempel i sociala nätverk. Flash p2p-videochatt ger inte multimediadataöverföring av hög kvalitet. Dessutom, för att mata ut röst- och videoströmmar från mikrofonen och videokameran i p2p flash-videochatt, måste du installera ett flash-plugin i din webbläsare.

Men den nya generationen av telekommunikationstjänster inkluderar webbkommunikation, som endast använder webbläsare och kontaktservrar som stöder WebRTC-protokoll och HTML5-specifikationen för att kommunicera över Internet. Alla användarenheter (PC, iPad, smartphones, etc.) utrustade med en sådan webbläsare kan ge högkvalitativa röst- och videosamtal, såväl som överföring av snabbtextmeddelanden och filer.

Så den nya tekniken för webbkommunikation (p2p-chattar, videochattar) är WebRTC-protokollet. WebRTC tillsammans med HTML5, CSS3 och JavaScript låter dig skapa olika webbapplikationer. WebRT är designat för att organisera webbkommunikation (peer-to-peer-nätverk) i realtid med hjälp av en peer-to-peer-arkitektur. P2P-chattar baserade på WebRTC tillhandahåller filöverföring, såväl som text-, röst- och videokommunikation mellan användare över Internet med enbart webbläsare utan användning av externa tillägg och plug-ins i webbläsaren.

I p2p-chattar används servern endast för att upprätta en p2p-anslutning mellan två webbläsare. För att skapa klientdelen av en p2p-chatt baserad på WebRTC-protokollet används HTML5, CSS3 och JavaScript. Klientapplikationen interagerar med webbläsare via WebRTC API.

WebRTC implementeras av tre JavaScript API:er:

  • RTCPeerConnection;
  • MediaStream(getUserMedia);
  • RTCDataChannel.

Webbläsare överför mediadata med hjälp av SRTP-protokollet, som körs ovanpå UDP. Eftersom NAT skapar problem för webbläsare (klienter) bakom NAT-routrar som använder p2p-anslutningar över Internet, används STUN för att kringgå NAT-översättare. STUN är ett klient-server-protokoll som körs ovanpå UDP-transportprotokollet. I p2p-chattar används som regel en offentlig STUN-server, och informationen som tas emot från den används för en UDP-anslutning mellan två webbläsare om de ligger bakom NAT.

Exempel på implementering av WebRTC-applikationer (p2p-chattar, röst- och videowebbchattar):
1. P2P-videochatt Bistri (videochatt med ett klick, p2p-chatt), baserat på WebRTC, kan öppnas på Bistri. Bistri fungerar i webbläsaren utan att installera ytterligare program och plugins. Kärnan i arbetet är som följer: öppna en p2p-videochatt med den angivna länken, efter registrering i gränssnittet som öppnas, bjud in partners, välj sedan partnern som är online och klicka på "videosamtal från listan över peer-klienter " knapp.

Som ett resultat kommer MediaStream (getUserMedia) att fånga mikrofonen + webbkameran, och servern kommer att utbyta signaleringsmeddelanden med den valda partnern. Efter att ha utbytt signalmeddelanden skapar PeerConnection API kanaler för att överföra röst- och videoströmmar. Dessutom överför Bistri snabbmeddelanden och filer. I fig. 1 visar en skärmdump av Bistri p2p-videochattgränssnittet.


Ris. 1. P2P videochatt Bistri

2. Twelephone (p2p videochatt, p2p chat, SIP Twelephone) - den här klientapplikationen är byggd på basis av HTML5 och WebRTC, vilket låter dig ringa röst- och videosamtal, samt skicka direkta textmeddelanden, d.v.s. Twelephone inkluderar test p2p-chatt, videochatt och SIP Twelephone. Det bör noteras att Twelephone stöder SIP-protokollet och nu kan du ringa och ta emot röst- och videosamtal från SIP-telefoner med ditt Twitter-konto som telefonnummer. Dessutom kan textmeddelanden matas in med rösten genom mikrofonen, och röstigenkänningsprogrammet skriver in texten i raden "Skicka ett meddelande".

Twelephone är en webbtelefoni som fungerar baserat på webbläsaren Google Chrome, från och med version 25, utan extra programvara. Twelephone utvecklades av Chris Matthieu. Twelephone-backend är byggd på Node.js. Servern (kontaktservern) används endast för att upprätta en p2p-anslutning mellan två webbläsare eller WebRTC-klienter. Twelephone-applikationen har inga egna auktoriseringsverktyg utan fokuserar på att ansluta till ett konto på Twitter.

I fig. 2 visar en skärmdump av Twelephone p2p-videochattgränssnittet.



Ris. 2. P2P Twelephone

3. Grupp-p2p-videochatt Conversat.io bygger på de senaste WebRTC- och HTML5-teknikerna. Conversat videochatt är utvecklad baserat på SimpleWebRTC-biblioteket och är avsedd för kommunikation mellan upp till 6 peer-klienter i ett rum (för kommunikation, ange namnet på det gemensamma rummet för peer-klienter i raden "Namnge konversationen"). P2P videochatt Conversat tillhandahåller kommunikationstjänster till användare utan att registrera sig på kontaktservern. I fig. Figur 3 visar en skärmdump av Conversat p2p-videochattgränssnittet.



Ris. 3. Gruppera P2P-videochatt Conversat.io

För att delta i P2P-videochatt baserade på WebRTC måste användare ha en webbläsare installerad som stöder WebRTC-protokollet och HTML5-specifikationen. För närvarande stöder webbläsare Google Chrome som börjar med version 25 och Mozilla Firefox Nightly WebRTC-protokollet och HTML5-specifikationen. WebRTC-applikationer är överlägsna Flash-applikationer när det gäller bild- och ljudöverföringskvalitet.

Europeiska internetanvändare är uppdelade i två delar: enligt en undersökning från Institutet för opinionsforskning i Allenbach (Tyskland) har Skype, chatt och snabbmeddelandesystem blivit en integrerad del av vardagen för 16,5 miljoner vuxna och barn, 9 miljoner använder dessa tjänster från fall efter fall, och 28 miljoner rör dem inte.

Det kan komma att förändras eftersom Firefox nu integrerar Real Time Communications-teknik (WebRTC) såväl som klienten själv. Att starta en ljud- och videochatt är nu inte svårare än att öppna en webbplats. Tjänster som Facebook och Skype, å andra sidan, är beroende av lösningar som använder en separat klient och skapar ett konto.

WebRTC kännetecknas inte bara av sin användarvänlighet. Denna metod låter dig till och med upprätta en direkt anslutning mellan två webbläsare. På så sätt passerar inte ljud- och videodata via en server där det kan finnas en överbelastning eller där administratören inte är särskilt känslig för integritet eller dataskydd. Tack vare den direkta anslutningen kräver WebRTC ingen registrering eller ett konto hos någon tjänst.

För att starta en konversation behöver du bara följa länken. Kommunikationen förblir privat eftersom dataströmmen är krypterad. Google började aktivt engagera sig i realtidskommunikation genom en webbläsare redan 2011, när det publicerade källkoden för sin WebRTC-implementering.

Strax efter detta fick Chrome och Firefox sina egna WebRTC-motorer. För närvarande är deras mobilversioner utrustade med både denna teknik och WebView 3.6-motorn installerad med Android 5.0, som används av applikationer.

För realtidskommunikation måste lämpliga JavaScript-gränssnitt implementeras i webbvisaren. Med GetUserMedia möjliggör programvaran inspelning från ljud- och videokällor, det vill säga webbkamera och mikrofon. RTCPeerConnection ansvarar för att upprätta anslutningen såväl som själva kommunikationen.

Parallellt med webbläsarintegration påskyndade en arbetsgrupp inom World Wide Web Consortium (W3C) WebRTC-standardiseringsprocessen. Det ska vara klart 2015.

WebRTC nöjer sig med lite

Att använda WebRTC-tjänsten kräver inte många resurser, eftersom servern bara ansluter samtalspartnerna. Att etablera en koppling är inte heller särskilt svårt. Först signalerar webbläsaren WebRTC-servern att den planerar att initiera ett samtal. Han får en HTTPS-länk från servern - kommunikationen är krypterad. Användaren skickar denna länk till sin samtalspartner. Webbläsaren ber sedan användaren om tillåtelse att komma åt webbkameran och mikrofonen.

För att upprätta en direkt strömmande anslutning med samtalspartnern får webbläsaren sin IP-adress och konfigurationsdata från WebRTC-tjänsten. Den andra personens webbvisare gör samma sak.

För att streaminganslutningen ska fungera smidigt och i bra kvalitet fungerar tre motorer i webbläsaren. Två av dem optimerar och komprimerar ljud- och videodata, den tredje ansvarar för deras transport. Den vidarebefordrar data med hjälp av Secure Real-time Transport Protocol (SRTP), som möjliggör krypterad realtidsströmning.

Om en direkt anslutning inte kan upprättas, letar WebRTC efter en annan sökväg. Detta händer till exempel när nätverksinställningarna hindrar STUN-servern från att kunna rapportera IP-adressen. WebRTC-standarden föreskriver att i detta fall kommer konversationen att äga rum, men med mellanliggande aktivering av TURN-servern (Traversal Using Relays around NAT). Så på webbplatsen netscan.co kan du kontrollera om WebRTC är implementerat på din dator och med din tillgång till nätverket.

Hur kopplingen görs

Du måste först registrera konversationen (1). WebRTC-tjänsten tillhandahåller en länk som måste skickas till samtalspartnern. Webbläsaren, med hjälp av STUN-servern, tar reda på sin egen IP-adress (2), skickar den till tjänsten och tar emot partnerns IP för att upprätta en direkt anslutning (3). Om STUN misslyckas, omdirigeras konversationen med TURN-servern (4).

Kommunikation med WebRTC-teknik i webbläsaren startas med JavaScript-kod. Därefter är det tre motorer som ansvarar för kommunikationen: röst- och videomotorerna samlar in multimediadata från webbkameran och mikrofonen, och transportmotorn kombinerar informationen och skickar strömmen i krypterad form med hjälp av SRTP (Secure Real-time Protocol).

Vilka webbläsare fungerar med WebRTC

Chrome och Firefox har en WebRTC-motor som använder tjänster som talky.io. Mozillas webbläsare kan arbeta direkt med sin egen klient.

Google och Mozilla fortsätter att utveckla idén om realtidskommunikation: Chrome kan vara värd för WebRTC-konferenser med flera deltagare, och Firefoxs nya Hello-klient utvecklades i samarbete med ett dotterbolag till telekomjätten Telefonica. Apple stannar vid sidan av för tillfället, du bör inte förvänta dig WebRTC i Safari än. Det finns dock många alternativa iOS-appar och Safari-plugins.

Microsoft går en lite annorlunda kurs. Som ägare till den konkurrerande Skype-tjänsten kommer detta företag inte att kapitulera så lätt för WebRTC. Istället utvecklar Microsoft en teknik som heter ORTC (Object Real-Time Communications) för Internet Explorer.

Skillnader från WebRTC, såsom olika codecs och protokoll för att etablera kontakt med servern, är små och kommer med tiden med största sannolikhet att utvecklas till ett tillägg till WebRTC-standarden som inkluderar dessa skillnader. Därmed är bara Apple kvar – som vanligt.

Foto: tillverkningsföretag; goodluz/Fotolia.com

Det mesta av materialet på WebRTC är fokuserat på applikationsnivån för kodning och bidrar inte till att förstå tekniken. Låt oss försöka gå djupare och ta reda på hur kopplingen uppstår, vad en sessionsbeskrivning och kandidater är, varför STUN- och TURN-servrar behövs.

WebRTC Introduktion

WebRTC är en webbläsarorienterad teknik som låter dig ansluta två klienter för videodataöverföring. Huvudfunktionerna är internt webbläsarstöd (det finns inget behov av tredjepartsimplementerade teknologier som adobe flash) och möjligheten att ansluta klienter utan användning av ytterligare servrar - peer-to-peer-anslutning (nedan, p2p).

Att upprätta en p2p-anslutning är en ganska svår uppgift, eftersom datorer inte alltid har offentliga IP-adresser, det vill säga adresser på Internet. På grund av det lilla antalet IPv4-adresser (och av säkerhetsskäl) utvecklades NAT-mekanismen, som gör att du kan skapa privata nätverk, till exempel för hemmabruk. Många hemroutrar stöder nu NAT och tack vare detta har alla hemenheter tillgång till Internet, även om internetleverantörer vanligtvis tillhandahåller en IP-adress. Offentliga IP-adresser är unika på Internet, men privata är det inte. Därför är det svårt att ansluta p2p.

För att förstå detta bättre, överväg tre situationer: båda noderna är på samma nätverk (Figur 1), båda noderna är på olika nätverk (en privat, den andra offentligt) (Figur 2) och båda noderna är i olika privata nätverk med samma IP-adresser (Figur 3).

Figur 1: Båda noderna i samma nätverk

Figur 2: Noder i olika nätverk (en privat, en offentlig)

Figur 3: Noder i olika privata nätverk, men med numeriskt lika adresser

I figurerna ovan indikerar den första bokstaven i tvåteckennotationen nodtypen (p = peer, r = router). På den första bilden är situationen gynnsam: noder i deras nätverk identifieras helt av nätverkets IP-adresser och kan därför ansluta till varandra direkt. I den andra figuren har vi två olika nätverk med liknande nodnummer. Det är här routrar (routrar) dyker upp, som har två nätverksgränssnitt – inom sitt nätverk och utanför sitt nätverk. Det är därför de har två IP-adresser. Vanliga noder har bara ett gränssnitt genom vilket de bara kan kommunicera inom sitt nätverk. Om de överför data till någon utanför deras nätverk, då endast använder NAT inuti routern (routern) och därför synlig för andra under routerns IP-adress - det är deras extern IP-adress. Så nod p1 har interiör IP = 192.168.0.200 Och extern IP = 10.50.200.5 , och den sista adressen kommer också att vara extern till alla andra noder i dess nätverk. Situationen är liknande för nod p2. Därför är deras kommunikation omöjlig om bara deras interna (egna) IP-adresser används. Du kan använda externa adresser, det vill säga routeradresser, men eftersom alla noder i samma privata nätverk har samma externa adress är detta ganska svårt. Detta problem kan lösas med hjälp av NAT-mekanismen

Vad händer om vi bestämmer oss för att ansluta noder via deras interna adresser? Data lämnar inte nätverket. För att förstärka effekten kan du föreställa dig situationen som visas i den sista figuren - båda noderna har samma interna adresser. Om de använder dem för att kommunicera, kommer varje nod att kommunicera med sig själv.

WebRTC hanterar sådana problem framgångsrikt med ICE-protokollet, vilket dock kräver användning av ytterligare servrar (STUN, TURN). Mer om allt detta nedan.

Två faser av WebRTC

För att ansluta två noder via WebRTC-protokollet (eller bara RTC, om två iPhones kommunicerar), måste du utföra några preliminära steg för att upprätta anslutningen. Detta är den första fasen - att upprätta en anslutning. Den andra fasen är videodataöverföring.

Det är värt att säga direkt att även om WebRTC-tekniken använder många olika kommunikationsmetoder i sitt arbete (TCP och UDP) och har flexibel växling mellan dem, så är denna teknik har inget protokoll för att överföra anslutningsdata. Inte förvånande, eftersom det inte är så lätt att ansluta två p2p-noder. Därför är det nödvändigt att ha några ytterligare en metod för dataöverföring som inte på något sätt är relaterad till WebRTC. Det kan vara en socketöverföring, HTTP-protokollet, det kan till och med vara SMTP- eller Russian Post-protokollet. Denna överföringsmekanism första data kallas signal. Inte mycket information behöver förmedlas. All data överförs i textform och är uppdelad i två typer - SDP och Ice Candidate. Den första typen används för att upprätta en logisk anslutning och den andra för en fysisk anslutning. Mer om allt detta senare, men för nu är det bara viktigt att komma ihåg att WebRTC kommer att ge oss lite information som måste överföras till en annan nod. Så snart vi överför all nödvändig information kommer noderna att kunna ansluta och vår hjälp kommer inte längre att behövas. Så signaleringsmekanismen vi behöver implementera är separat, kommer att användas endast när den är ansluten, men kommer inte att användas vid överföring av videodata.

Så låt oss överväga den första fasen - anslutningsetableringsfasen. Den består av flera punkter. Låt oss titta på denna fas först för noden som initierar anslutningen och sedan för den som väntar.

  • Initiativtagare (uppringare):
  • Erbjud att starta videodataöverföring (createOffer)
  • Skaffa din SDP SDP)
  • Ta emot din iskandidat Iskandidat )
  • Samtal väntar (callee):
  • Ta emot en lokal (din) mediaström och ställa in den för överföring (getUserMediaStream)
  • Få ett erbjudande om att starta videodataöverföring och skapa ett svar (createAnswer)
  • Ta emot sitt SDP-objekt och skicka det genom signaleringsmekanismen (SDP)
  • Ta emot dina Ice-kandidatobjekt och skicka dem genom en signaleringsmekanism (Iskandidat)
  • Ta emot en fjärrstyrd (utländsk) mediaström och visa den på skärmen (onAddStream)

Den enda skillnaden ligger i den andra punkten.

Trots den uppenbara komplexiteten i stegen finns det faktiskt tre av dem: att skicka din egen mediaström (punkt 1), ställa in anslutningsparametrar (punkt 2-4), ta emot någon annans mediaström (punkt 5). Det svåraste steget är det andra steget, eftersom det består av två delar: att etablera fysisk Och logisk anslutningar. Den första indikerar väg, längs vilka paket måste resa för att komma från en nätverksnod till en annan. Den andra indikerar video-/ljudparametrar– vilken kvalitet man ska använda, vilka codecs man ska använda.

Mentalt sett bör steget createOffer eller createAnswer vara kopplat till stegen för att skicka SDP- och Ice-kandidatobjekt.

Grundläggande enheter Mediaströmmar (MediaStream)

Huvudessensen är mediaströmmen, det vill säga strömmen av video- och ljuddata, bild och ljud. Det finns två typer av mediaströmmar - lokala och fjärranslutna. Den lokala tar emot data från inmatningsenheter (kamera, mikrofon) och den fjärranslutna via nätverket. Således har varje nod både en lokal och en fjärrtråd. I WebRTC finns det ett MediaStream-gränssnitt för strömmar och det finns också ett LocalMediaStream-undergränssnitt specifikt för en lokal ström. I JavaScript kan du bara stöta på den första, men om du använder libjingle kan du också stöta på den andra.

WebRTC har en ganska förvirrande hierarki i en tråd. Varje stream kan bestå av flera mediaspår (MediaTrack), som i sin tur kan bestå av flera mediekanaler (MediaChannel). Och det kan också finnas flera medieströmmar själva.

Låt oss titta på allt i ordning. För att göra detta, låt oss ha några exempel i åtanke. Låt oss säga att vi inte bara vill överföra en video av oss själva, utan också en video av vårt bord, på vilket det ligger ett papper som vi ska skriva något på. Vi kommer att behöva två videor (oss + bord) och ett ljud (oss). Det är klart att vi och tabellen bör delas upp i olika trådar, eftersom dessa uppgifter förmodligen är svagt beroende av varandra. Därför kommer vi att ha två MediaStreams – en för oss och en för bordet. Den första kommer att innehålla både video- och ljuddata, och den andra kommer bara att innehålla video (Figur 4).

Figur 4: Två olika mediaströmmar. En för oss, en för vårt bord

Det är omedelbart klart att en mediaström som ett minimum måste innehålla förmågan att innehålla data av olika slag - video och ljud. Detta tas hänsyn till i tekniken och därför implementeras varje typ av data genom ett mediaspår MediaTrack. Mediaspåret har en speciell egenskapstyp, som avgör om det är video eller ljud (Figur 5)

Figur 5: Medieströmmar består av mediaspår

Hur kommer allt att hända i programmet? Vi kommer att skapa två mediaströmmar. Sedan kommer vi att skapa två videospår och ett ljudspår. Låt oss få tillgång till kamerorna och mikrofonen. Låt oss tala om för varje spår vilken enhet som ska användas. Låt oss lägga till ett video- och ljudspår till den första mediaströmmen och ett videospår från en annan kamera till den andra mediaströmmen.

Men hur skiljer vi mediaströmmar i andra änden av anslutningen? För att göra detta har varje mediaström en etikettegenskap - strömmens etikett, dess namn (Figur 6). Mediaspår har samma egenskap. Även om det vid första anblicken verkar som att video kan särskiljas från ljud på andra sätt.

Figur 6: Mediaströmmar och spår identifieras med etiketter

Så om mediaspår kan identifieras genom en tagg, varför behöver vi då använda två mediaströmmar för vårt exempel, istället för en? När allt kommer omkring kan du sända en mediaström, men använda olika spår i den. Vi har nått en viktig egenskap hos mediaströmmar – de synkronisera media spår. Olika mediaströmmar synkroniseras inte med varandra, utan inom varje mediaström alla spår spelas samtidigt.

Så om vi vill att våra ord, våra ansiktskänslor och vårt papper ska spelas samtidigt, är det värt att använda en mediaström. Om detta inte är så viktigt är det mer lönsamt att använda olika strömmar - bilden blir jämnare.

Om något spår måste inaktiveras under överföringen kan du använda egenskapen enabled för mediaspåret.

Slutligen är det värt att tänka på stereoljud. Som ni vet är stereoljud två olika ljud. Och de måste också överföras separat. Mediakanaler används för detta. Ett medialjudspår kan ha många kanaler (till exempel 6 om du behöver 5+1 ljud). Det finns också kanaler inne i mediaspåren förstås. synkroniserad. För video används vanligtvis bara en kanal, men flera kan användas, till exempel för överliggande reklam.

För att sammanfatta: Vi använder en mediaström för att överföra video- och ljuddata. Inom varje mediaström synkroniseras data. Vi kan använda flera mediaströmmar om vi inte behöver synkronisering. Inuti varje mediaström finns två typer av mediaspår - för video och för ljud. Det finns vanligtvis inte mer än två spår, men det kan finnas fler om du behöver sända flera olika videor (av samtalspartnern och hans bord). Varje spår kan bestå av flera kanaler, vilket vanligtvis endast används för stereoljud.

I den enklaste videochattsituationen kommer vi att ha en lokal mediaström, som kommer att bestå av två spår - ett videospår och ett ljudspår, som var och en kommer att bestå av en huvudkanal. Videospåret är ansvarigt för kameran, ljudspåret är för mikrofonen och mediaströmmen är behållaren för dem båda.

Session Descriptor (SDP)

Olika datorer kommer alltid att ha olika kameror, mikrofoner, grafikkort och annan utrustning. Det finns många alternativ de har. Allt detta måste koordineras för mediaöverföring av data mellan två nätverksnoder. WebRTC gör detta automatiskt och skapar ett speciellt objekt - SDP session descriptor. Skicka detta objekt till en annan nod och mediadata kan överföras. Bara det finns ingen koppling till en annan nod ännu.

Alla signaleringsmekanismer används för detta. SDP kan överföras antingen genom uttag, eller av en person (berätta det till en annan nod via telefon), eller med rysk post. Allt är väldigt enkelt - du kommer att få en färdig SDP och du måste skicka den. Och när den tas emot på andra sidan, överför den till WebRTC-avdelningen. Sessionsbeskrivningen lagras som text och kan ändras i dina applikationer, men detta är i allmänhet inte nödvändigt. Som ett exempel, när du ansluter stationär ↔ telefon, ibland måste du tvinga fram valet av önskad ljudcodec.

Vanligtvis när du upprättar en anslutning måste du ange någon typ av adress, till exempel en URL. Detta är inte nödvändigt här, eftersom du genom signaleringsmekanismen själv skickar data till dess destination. För att indikera för WebRTC att vi vill upprätta en p2p-anslutning måste vi anropa createOffer-funktionen. Efter att ha anropat den här funktionen och specificerat en speciell callback 'a, kommer ett SDP-objekt att skapas och skickas till samma callback. Allt som krävs av dig är att överföra detta objekt över nätverket till en annan nod (samtalspartner). Efter detta kommer data att komma till andra änden genom signaleringsmekanismen, nämligen detta SDP-objekt. Denna sessionsbeskrivning är främmande för denna nod och bär därför användbar information. Att ta emot detta objekt är en signal för att starta anslutningen. Därför måste du godkänna detta och anropa createAnswer-funktionen. Det är en komplett analog till createOffer. Återigen kommer den lokala sessionsbeskrivningen att skickas till din återuppringning och den måste skickas tillbaka genom signaleringsmekanismen.

Det är värt att notera att du kan anropa createAnswer-funktionen först efter att ha tagit emot någon annans SDP-objekt. Varför? Eftersom det lokala SDP-objektet som kommer att genereras när createAnswer anropas måste förlita sig på fjärr-SDP-objektet. Endast i det här fallet är det möjligt att samordna dina videoinställningar med inställningarna för din samtalspartner. Du bör inte heller anropa createAnswer och createOffer innan du tar emot den lokala mediaströmmen - de har inget att skriva till SDP-objektet.

Eftersom WebRTC har möjlighet att redigera ett SDP-objekt måste det installeras efter att ha mottagit en lokal deskriptor. Det kan tyckas lite konstigt att vi måste överföra till WebRTC vad det själv gav oss, men det är protokollet. När ett fjärrhandtag tas emot måste det också installeras. Därför måste du installera två deskriptorer på en nod - din och någon annans (det vill säga lokal och fjärransluten).

Efter det här handslag noder känner till varandras önskemål. Till exempel, om nod 1 stöder codec A och B, och nod 2 stöder codec B och C, då, eftersom varje nod känner till sina egna och den andras deskriptorer, kommer båda noderna att välja codec B (Figur 7). Anslutningslogiken är nu etablerad och mediaströmmar kan överföras, men det finns ett annat problem - noderna är fortfarande bara anslutna med en signalmekanism.


Figur 7: Codec-förhandling

Iskandidat

WebRTC-tekniken försöker förvirra oss med sin nya metodik. När du upprättar en anslutning anges inte adressen till den nod som du vill ansluta till. Installerade först logisk anslutning, inte fysisk, även om det alltid gjordes motsatsen. Men detta kommer inte att verka konstigt om vi inte glömmer att vi använder en signalmekanism från tredje part.

Så anslutningen har redan upprättats (logisk anslutning), men det finns fortfarande ingen väg längs vilken nätverksnoderna kan överföra data. Det är inte så enkelt, men låt oss börja enkelt. Låt noderna vara på samma privata nätverk. Som vi redan vet kan de enkelt ansluta till varandra med sina interna IP-adresser (eller kanske några andra, om inte TCP/IP används).

Genom någon callback 'och WebRTC informerar oss om Ice-kandidatobjekt. De kommer också i textform och, precis som sessionsbeskrivningar, behöver de helt enkelt skickas via en signaleringsmekanism. Om sessionsbeskrivningen innehöll information om våra inställningar på kamera- och mikrofonnivå, så innehåller kandidaterna information om vår plats i nätverket. Skicka dem vidare till en annan nod, så kommer den att kunna ansluta fysiskt till oss, och eftersom den redan har en sessionsbeskrivning, kommer den logiskt att kunna ansluta och data kommer att "flöda". Om han kommer ihåg att skicka sitt kandidatobjekt till oss, det vill säga information om var han själv befinner sig i nätverket, då kommer vi att kunna knyta an till honom. Låt oss här notera ytterligare en skillnad från den klassiska klient-server-interaktionen. Kommunikation med HTTP-servern sker enligt request-response-schemat, klienten skickar data till servern som bearbetar den och skickar den via adressen som anges i förfrågningspaketet. I WebRTC behöver du veta två adresser och koppla ihop dem på båda sidor.

Skillnaden mot sessionsbeskrivningar är att endast fjärrkandidater behöver installeras. Redigering här är förbjuden och kan inte ge någon fördel. I vissa WebRTC-implementeringar behöver kandidater installeras först efter att sessionsbeskrivningar har ställts in.

Varför fanns det bara en sessionsbeskrivning, men det kunde finnas många kandidater? Eftersom platsen på nätverket inte bara kan bestämmas av dess interna IP-adress, utan också av routerns externa adress, och inte nödvändigtvis bara en, samt adresserna till TURN-servrar. Resten av stycket kommer att ägnas åt en detaljerad diskussion om kandidaterna och hur man kopplar ihop noder från olika privata nätverk.

Så två noder finns på samma nätverk (Figur 8). Hur identifierar man dem? Använder IP-adresser. Inget annat sätt. Det är sant att du fortfarande kan använda olika transporter (TCP och UDP) och olika portar. Detta är informationen som finns i kandidatobjektet - IP, PORT, TRANSPORT och några andra. Låt till exempel använda UDP-transport och port 531.

Figur 8: Två noder finns på samma nätverk

Sedan, om vi är i nod p1, kommer WebRTC att ge oss ett sådant kandidatobjekt - . Detta är inte ett exakt format, bara ett diagram. Om vi ​​är på nod p2, då är kandidaten . Genom signaleringsmekanismen kommer pl att ta emot p2:s kandidat (det vill säga platsen för nod p2, nämligen dess IP och PORT). Då kan p1 ansluta till p2 direkt. Mer korrekt kommer p1 att skicka data till 10.50.150.3:531 i hopp om att den når p2. Det spelar ingen roll om denna adress tillhör nod p2 eller någon mellanhand. Det enda viktiga är att data kommer att skickas via denna adress och kan nå p2.

Så länge som noder finns på samma nätverk är allt enkelt och lätt - varje nod har bara ett kandidatobjekt (alltid betyder sitt eget, det vill säga dess plats i nätverket). Men det kommer att finnas många fler kandidater när noderna är inne annorlunda nätverk.

Låt oss gå vidare till ett mer komplext fall. En nod kommer att vara placerad bakom routern (mer exakt, bakom NAT), och den andra noden kommer att vara placerad i samma nätverk med denna router (till exempel på Internet) (Figur 9).

Figur 9: En nod ligger bakom NAT, den andra inte

Det här fallet har en särskild lösning på problemet, som vi nu ska överväga. En hemrouter innehåller vanligtvis en NAT-tabell. Detta är en speciell mekanism utformad för att ge noder inuti routerns privata nätverk åtkomst till till exempel webbplatser.

Låt oss anta att webbservern är ansluten till Internet direkt, det vill säga den har en offentlig IP *-adress. Låt detta vara nod p2. Nod p1 (webbklient) skickar en förfrågan till adressen 10.50.200.10. Först går data till router r1, eller snarare till dess interiör gränssnitt 192.168.0.1. Därefter kommer routern ihåg källadressen (adress p1) och anger den i en speciell NAT-tabell och ändrar sedan källadressen till sin egen (p1 → r1). Vidare, på mitt sätt extern gränssnittet skickar routern data direkt till p2 webbservern. Webbservern bearbetar data, genererar ett svar och skickar tillbaka det. Skickar r1 till routern, eftersom den finns i returadressen (routern ersatte adressen med sin egen). Routern tar emot data, tittar på NAT-tabellen och vidarebefordrar data till nod p1. Routern fungerar som mellanhand här.

Vad händer om flera noder från det interna nätverket samtidigt kommer åt det externa nätverket? Hur kommer routern att förstå vem den ska skicka svaret tillbaka till? Detta problem löses med hjälp av hamnar. När en router ersätter värdadressen med sin egen, ersätter den också porten. Om två noder ansluter till Internet, ersätter routern sina källportar med annorlunda. Sedan, när paketet från webbservern kommer tillbaka till routern, kommer routern att förstå av porten vem paketet är tilldelat. Exempel nedan.

Låt oss återgå till WebRTC-tekniken, eller mer exakt, till den del av den som använder ICE-protokollet (därav Ice-kandidaterna). Nod p2 har en kandidat (dess plats i nätverket är 10.50.200.10), och nod p1, som ligger bakom routern med NAT, kommer att ha två kandidater - lokal (192.168.0.200) och routerkandidat (10.50.200.5). Den första är inte användbar, men den genereras ändå, eftersom WebRTC ännu inte vet något om fjärrnoden - den kan vara eller inte vara på samma nätverk. Den andra kandidaten kommer väl till pass, och som vi redan vet kommer hamnen (för att ta sig igenom NAT) att spela en viktig roll.

En post i NAT-tabellen genereras endast när data lämnar det interna nätverket. Därför måste nod pl sända data först och först efter det kan data från nod p2 nå nod pl.

På praktik båda noderna kommer att ligga bakom NAT. För att skapa en post i varje routers NAT-tabell måste värdarna skicka något till fjärrvärden, men den här gången kan varken den förra nå den senare eller vice versa. Detta beror på det faktum att noder inte känner till sina externa IP-adresser, och att skicka data till interna adresser är meningslöst.

Men om de externa adresserna är kända kommer anslutningen lätt att upprättas. Om den första noden skickar data till den andra nodens router kommer routern att ignorera det, eftersom dess NAT-tabell fortfarande är tom. Men i routern för den första noden dök en nödvändig post upp i NAT-tabellen. Om nu den andra noden skickar data till den första nodens router, kommer routern att framgångsrikt överföra den till den första noden. Nu har NAT-tabellen för den andra routern också nödvändiga data.

Problemet är att för att ta reda på din externa IP-adress behöver du en nod på det offentliga nätverket. För att lösa detta problem används ytterligare servrar som är direkt anslutna till Internet. Med deras hjälp skapas också värdefulla poster i NAT-tabellen.

STUN och TURN servrar

När du initierar WebRTC måste du specificera tillgängliga STUN- och TURN-servrar, som vi hädanefter kommer att kalla ICE-servrar. Om servrar inte är specificerade kommer endast noder på samma nätverk (anslutna till det utan NAT) att kunna ansluta. Det är omedelbart värt att notera att för 3g-nätverk är användningen av TURN-servrar obligatorisk.

BEDÖVA serverär helt enkelt en server på Internet som returnerar en returadress, det vill säga adressen till avsändarens nod. Värden bakom routern kontaktar STUN-servern för att passera NAT. Paketet som kom till STUN-servern innehåller källadressen - routeradressen, det vill säga den externa adressen till vår nod. Det här är adressen STUN som servern skickar tillbaka. Således får noden sin externa IP-adress och porten genom vilken den är tillgänglig från nätverket. Därefter använder WebRTC denna adress för att skapa ytterligare en kandidat (extern routeradress och port). Nu finns det en post i routerns NAT-tabell som tillåter paket som skickas till routern på den port som krävs för att nå vår nod.

Låt oss titta på denna process med ett exempel.

Exempel (STUN-serverdrift)

STUN-servern kommer att betecknas med s1. Routern, som tidigare, är genom r1, och noden är genom p1. Du måste också övervaka NAT-tabellen - vi betecknar den som r1_nat. Dessutom innehåller denna tabell vanligtvis många poster från olika noder i subnätet - de kommer inte att ges.

Så i början har vi en tom tabell r1_nat.

Tabell 2: Pakethuvud

Nod p1 skickar detta paket till router r1 (det spelar ingen roll hur, olika teknologier kan användas i olika undernät). Routern måste ersätta källadressen Src IP, eftersom adressen som anges i paketet uppenbarligen inte är lämplig för ett externt subnät, dessutom är adresser från ett sådant intervall reserverade, och inte en enda adress på Internet har en sådan adress. Routern gör en substitution i paketet och skapar en ny post i sin r1_nat-tabell. För att göra detta måste han komma med ett portnummer. Låt oss komma ihåg att eftersom flera noder inom ett subnät kan komma åt det externa nätverket måste ytterligare information lagras i NAT-tabellen så att routern kan avgöra vilken av dessa flera noder som är avsedd för returpaketet från servern. Låt routern komma med port 888.

Ändrad pakethuvud:

Tabell 4: NAT-tabellen har uppdaterats med en ny post

Här är IP-adressen och porten för subnätet exakt samma som originalpaketet. Faktum är att när vi postbackar måste vi ha ett sätt att helt återställa dem. IP-adressen för det externa nätverket är adressen till routern, och porten har ändrats till den som uppfanns av routern.

Den riktiga porten på vilken nod p1 accepterar anslutningen är naturligtvis 35777, men servern skickar data till fiktiv port 888, som kommer att ändras av routern till den riktiga 35777.

Så routern ersatte källadressen och porten i pakethuvudet och lade till en post i NAT-tabellen. Nu skickas paketet över nätverket till servern, det vill säga nod s1. Vid ingången har s1 följande paket:

Src IP Src PORT Dest IP Dest PORT
10.50.200.5 888 12.62.100.200 6000

Tabell 5: STUN-server tog emot paket

Totalt vet STUN-servern att den tagit emot ett paket från adressen 10.50.200.5:888. Nu skickar servern denna adress tillbaka. Det är värt att stanna här och ta en ny titt på det vi just tittade på. Tabellerna ovan är ett utdrag från rubrik paket, inte alls från det innehåll. Vi pratade inte om innehållet, eftersom det inte är så viktigt - det beskrivs på något sätt i STUN-protokollet. Nu ska vi överväga, förutom titeln, innehållet. Det kommer att vara enkelt och innehålla routeradressen - 10.50.200.5:888, även om vi tog det från rubrik paket. Detta görs inte ofta; protokoll bryr sig vanligtvis inte om information om nodadresser, det är bara viktigt att paketen levereras till sin avsedda destination. Här tittar vi på ett protokoll som upprättar en väg mellan två noder.

Så nu har vi ett andra paket som går i motsatt riktning:

Tabell 7: STUN-servern skickar ett paket med detta innehåll

Därefter färdas paketet över nätverket tills det når det externa gränssnittet på routern r1. Routern förstår att paketet inte är avsett för det. Hur förstår han detta? Detta kan endast bestämmas av hamnen. Han använder inte port 888 för sina personliga ändamål, utan använder den för NAT-mekanismen. Därför tittar routern på den här tabellen. Tittar på kolumnen Extern PORT och letar efter en rad som matchar Dest PORT från det inkommande paketet, det vill säga 888.

Intern IP Intern PORT Extern IP Extern PORT
192.168.0.200 35777 10.50.200.5 888

Tabell 8: NAT-tabell

Vi har tur, en sådan linje finns. Om vi ​​hade otur skulle paketet helt enkelt slängas. Nu måste du förstå vilken nod på subnätet som ska skicka detta paket. Inget behov av att rusa, låt oss återigen komma ihåg vikten av portar i denna mekanism. Samtidigt kunde två noder på subnätet skicka förfrågningar till det externa nätverket. Sedan, om routern kom med port 888 för den första noden, skulle den för den andra komma med port 889. Låt oss anta att detta hände, det vill säga att tabellen r1_nat ser ut så här:

Tabell 10: Routern ersätter mottagaradressen

Src IP Src PORT Dest IP Dest PORT
12.62.100.200 6000 192.168.0.200 35777

Tabell 11: Routern ändrade mottagarens adress

Paketet anländer framgångsrikt till nod p1 och genom att titta på innehållet i paketet lär sig noden om sin externa IP-adress, det vill säga adressen till routern på det externa nätverket. Han känner också till porten som routern passerar genom NAT.

Vad kommer härnäst? Vad tjänar allt detta till? En förmån är en post i tabellen r1_nat. Om nu någon skickar ett paket med port 888 till router r1, så kommer routern att vidarebefordra detta paket till nod p1. Detta skapade en liten smal passage till den dolda noden p1.

Från exemplet ovan kan du få en uppfattning om hur NAT fungerar och essensen av en STUN-server. I allmänhet är ICE-mekanismen och STUN/TURN-servrarna exakt inriktade på att övervinna NAT-restriktioner.

Mellan noden och servern kan det inte finnas en router utan flera. I det här fallet kommer noden att få adressen till routern som är den första att komma åt samma nätverk som servern. Med andra ord kommer vi att få adressen till routern som är ansluten till STUN-servern. För p2p-kommunikation är det precis vad vi behöver, om vi inte glömmer det faktum att varje router kommer att lägga till raden vi behöver till NAT-tabellen. Därför blir vägen tillbaka lika smidig igen.

TURN server är en förbättrad STUN-server. Härifrån bör du omedelbart ta bort att vilken TURN-server som helst också kan fungera som en STUN-server. Men det finns också fördelar. Om p2p-kommunikation är omöjlig (som till exempel i 3g-nätverk), växlar servern till reläläge, det vill säga den fungerar som en mellanhand. Vi pratar givetvis inte om någon p2p då, men utanför ICE-mekanismen tror noder att de kommunicerar direkt.

I vilka fall behövs en TURN-server? Varför finns det inte tillräckligt med STUN-server? Faktum är att det finns flera typer av NAT. De ersätter IP-adressen och porten på samma sätt, men några av dem har ytterligare skydd mot "förfalskning" inbyggt i dem. Till exempel i symmetrisk NAT-tabellen lagrar ytterligare två parametrar - IP och port för fjärrvärden. Ett paket från det externa nätverket passerar genom NAT till det interna nätverket endast om källadressen och porten matchar de som registrerats i tabellen. Därför misslyckas tricket med STUN-servern - NAT-tabellen lagrar adressen och porten för STUN-servern och, när routern tar emot ett paket från WebRTC-samtalaren, kasserar den det eftersom det är "förfalskat". Det kom inte från STUN-servern.

Det behövs alltså en TURN-server i fallet då båda samtalspartnerna är bakom symmetrisk NAT (var och en till sin egen).

Kort sammanfattning

Här är några uttalanden om WebRTC-enheter som du alltid bör ha i åtanke. De beskrivs i detalj ovan. Om något av påståendena inte verkar helt klart för dig, läs de relevanta styckena igen.

  • Mediaström
    • Video- och ljuddata paketeras i mediaströmmar
    • Mediaströmmar synkroniserar mediespåren som utgörs av
    • Olika mediaströmmar synkroniseras inte med varandra
    • Mediaströmmar kan vara lokala och fjärranslutna, den lokala är vanligtvis ansluten till en kamera och mikrofon, de fjärranslutna tar emot data från nätverket i krypterad form
    • Det finns två typer av mediaspår - för video och för ljud.
    • Mediaspår har möjlighet att slå på/stänga av
    • Mediespår består av mediakanaler
    • Mediaspår synkroniserar de mediekanaler som utgörs av
    • Medieströmmar och mediaspår har etiketter som de kan särskiljas med
  • Sessionshandtag
    • Sessionsbeskrivningen används för att logiskt ansluta två nätverksnoder
    • Sessionsbeskrivningen lagrar information om tillgängliga metoder för att koda video- och ljuddata
    • WebRTC använder en extern signaleringsmekanism - uppgiften att vidarebefordra sessionsbeskrivningar (sdp) faller på applikationen
    • Den logiska anslutningsmekanismen består av två steg - erbjudande (erbjudande) och svar (svar)
    • Generering av en sessionsbeskrivning är omöjlig utan att använda en lokal mediaström i fallet med ett erbjudande och är omöjligt utan att använda en fjärrsessionsbeskrivning i fallet med ett svar.
    • Den resulterande beskrivningen måste ges till WebRTC-implementeringen, och det spelar ingen roll om denna beskrivning tas emot på distans eller lokalt från samma WebRTC-implementering
    • Det är möjligt att redigera sessionsbeskrivningen något
  • Kandidater
    • Iskandidat är adressen till en nod i nätverket
    • Nodadressen kan vara din egen, eller det kan vara adressen till en router eller TURN-server
    • Det finns alltid många kandidater
    • Kandidaten består av en IP-adress, port och transporttyp (TCP eller UDP)
    • Kandidater används för att upprätta en fysisk anslutning mellan två noder i ett nätverk
    • Kandidater måste också skickas via en signaleringsmekanism
    • Kandidater måste också skickas till WebRTC-implementationer, men endast fjärrstyrda
    • I vissa WebRTC-implementeringar kan kandidater endast överföras efter att en sessionsbeskrivning har ställts in
  • STUN/TURN/ICE/NAT
    • NAT är en mekanism för att ge åtkomst till ett externt nätverk
    • Hemroutrar stöder en speciell NAT-tabell
    • Routern ersätter adresserna i paketen - källadressen med sin egen, om paketet går till ett externt nätverk, och mottagaradressen med värdadressen på det interna nätverket, om paketet kom från ett externt nätverk
    • För att ge flerkanalsåtkomst till ett externt nätverk använder NAT portar
    • ICE - NAT Traversal Engine
    • STUN- och TURN-servrar – assistentservrar för NAT-traversering
    • STUN-servern låter dig skapa de nödvändiga posterna i NAT-tabellen och returnerar även värdens externa adress
    • TURN-servern generaliserar STUN-mekanismen och gör att den alltid fungerar
    • I värsta fall används TURN-servern som mellanhand (relä), det vill säga p2p förvandlas till en klient-server-klient-anslutning.

WebRTC är ett API som tillhandahålls av webbläsaren och låter dig organisera en P2P-anslutning och överföra data direkt mellan webbläsare. Det finns en hel del tutorials på Internet om hur du skriver din egen videochatt med WebRTC. Här är till exempel en artikel om Habré. De är dock alla begränsade till att ansluta två klienter. I den här artikeln kommer jag att försöka prata om hur man organiserar anslutning och utbyte av meddelanden mellan tre eller flera användare med WebRTC.

RTCPeerConnection-gränssnittet är en peer-to-peer-anslutning mellan två webbläsare. För att ansluta tre eller fler användare måste vi organisera ett mesh-nätverk (ett nätverk där varje nod är ansluten till alla andra noder).
Vi kommer att använda följande schema:

  • När vi öppnar sidan kontrollerar vi förekomsten av rums-ID i location.hash
  • Om rums-ID inte anges, generera ett nytt
  • Vi skickar ett meddelande till signalservern att vi vill ansluta till det angivna rummet
  • Signalservern skickar ett meddelande om en ny användare till andra klienter i det här rummet
  • Kunder som redan finns i rummet skickar ett SDP-erbjudande till nykomlingen
  • Nybörjare svarar på erbjudanden
  • 0. Signalserver

    Som ni vet, även om WebRTC ger möjlighet till P2P-anslutning mellan webbläsare, kräver dess drift fortfarande ytterligare transport för utbyte av tjänstemeddelanden. I det här exemplet är transporten som används en WebSocket-server skriven i Node.JS med socket.io:

    Var socket_io = require("socket.io"); module.exports = function (server) ( var users = (); var io = socket_io(server); io.on("connection", function(socket) ( // Vill att en ny användare ska gå med i rummet socket.on( "rum", function(meddelande) ( var json = JSON.parse(meddelande); // Lägg till socket till listan över användare användare = socket; if (socket.room !== odefinierat) ( // Om socket är redan i något rum, avsluta det socket.leave(socket.room ) // Ange det begärda rummet socket.room; ny deltagare socket.broadcast.to(socket.room).emit("new", json.id ) // Meddelande relaterat till WebRTC (SDP-erbjudande, SDP-svar eller ICE-kandidat) socket.on("webrtc", funktion); (meddelande) ( var json = JSON.parse(meddelande); if (json.to !== odefinierade && användare !== odefinierade) ( // Om meddelandet anger en mottagare och den mottagaren som servern känner till, skickar vi meddelande bara till det... users.emit("webrtc", meddelande); ) else ( // ...annars anser vi att meddelandet är broadcast socket.broadcast.to(socket.room).emit("webrtc", meddelande); ) )); // Någon har kopplat från socket.on("disconnect", function() ( // När en klient kopplar från, meddela andra om det socket.broadcast.to(socket.room).emit("leave", socket.user_id); ta bort användare )); )); );

    1.index.html

    Källkoden för själva sidan är ganska enkel. Jag uppmärksammade medvetet inte layout och andra skönheter, eftersom den här artikeln inte handlar om det. Om någon vill göra det vackert blir det inte svårt.

    WebRTC Chat Demo Ansluten till 0 kamrater
    Skicka

    2. main.js 2.0. Hämta länkar till sidelement och WebRTC-gränssnitt var chatlog = document.getElementById("chatlog"); var message = document.getElementById("meddelande"); var connection_num = document.getElementById("connection_num"); var room_link = document.getElementById("rumslänk");

    Vi måste fortfarande använda webbläsarprefix för att komma åt WebRTC-gränssnitt.

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

    2.1. Fastställande av rums-ID

    Här behöver vi en funktion för att generera ett unikt rum och användaridentifierare. Vi kommer att använda UUID för dessa ändamål.

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

    Låt oss nu försöka extrahera rumsidentifieraren från adressen. Om en inte specificeras kommer vi att generera en ny. Låt oss visa en länk till det aktuella rummet på sidan, och samtidigt generera identifieraren för den aktuella användaren.

    Var RUM = location.hash.substr(1); if (!ROOM) ( ROOM = uuid(); ) room_link.innerHTML = "Länka till rummet"; var ME = uuid();

    2.2. WebSocket

    Omedelbart när vi öppnar sidan kommer vi att ansluta till vår signalserver, skicka en begäran om att komma in i rummet och ange meddelandehanterare.

    // Ange att när du stänger ett meddelande måste du skicka ett meddelande till servern om denna var socket = io.connect("", ("sync disconnect on unload": true)); socket.on("webrtc", socketReceived); socket.on("ny", socketNewPeer); // Skicka omedelbart en begäran om att komma in i rummet socket.emit("rum", JSON.stringify((id: MIG, rum: ROOM))); // Hjälpfunktion för att skicka adressmeddelanden relaterade till WebRTC-funktionen sendViaSocket(typ, meddelande, till) ( socket.emit("webrtc", JSON.stringify((id: MIG, till: till, typ: typ, data: meddelande ) ));

    2.3. PeerConnection-inställningar

    De flesta internetleverantörer tillhandahåller Internetanslutningar via NAT. På grund av detta blir direkt anslutning inte en så trivial sak. När vi skapar en anslutning måste vi ange en lista över STUN- och TURN-servrar som webbläsaren kommer att försöka använda för att kringgå NAT. Vi kommer också att ange ett par ytterligare alternativ för anslutning.

    Var server = ( iceServers: [ (url: "stun:23.21.150.121"), (url: "stun:stun.l.google.com:19302"), (url: "turn:numb.viagenie.ca", credential: "ditt lösenord går hit", användarnamn: " [e-postskyddad]") ] ); var options = ( valfritt: [ (DtlsSrtpKeyAgreement: true), // krävs för anslutning mellan Chrome och Firefox (RtpDataChannels: true) // krävs i Firefox för att använda DataChannels API ] )

    2.4. Ansluter en ny användare

    När en ny peer läggs till i rummet skickar servern ett nytt meddelande till oss. Enligt meddelandehanterarna ovan kommer socketNewPeer-funktionen att anropas.

    Var kamrater = (); function socketNewPeer(data) ( peers = (candidateCache: ); // Skapa en ny anslutning var pc = new PeerConnection(server, optioner); // Initiera den initConnection(pc, data, "erbjudande"); // Spara peers i listan peers.connection = pc; // Skapa en datakanal genom vilken meddelanden kommer att utbytas var channel = pc.createDataChannel("mychannel", ()); ; // Skapa SDP-erbjudande pc.createOffer(function(offer) ( pc.setLocalDescription(offer); ) ) function initConnection(pc, id, sdpType) ( pc.onicecandidate = function (event) ( if (event.candidate) ( // När en ny ICE-kandidat upptäcks, lägg till den i listan för vidare sändning av peers.candidateCache.push(event.candidate ) else ( // När kandidatupptäckten är klar kommer hanteraren att anropas igen, men utan kandidat // I det här fallet skickar vi först till peeren ett SDP-erbjudande eller SDP-svar (beroende på funktionsparametern)... sendViaSocket(sdpType, pc.localDescription, id); // ...och sedan alla tidigare hittade ICE-kandidater för (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 says: " + e.data + ""; }; }

    2.5. SDP-erbjudande, SDP-svar, ICE-kandidat

    När vi får ett av dessa meddelanden ringer vi hanteraren för motsvarande meddelande.

    Funktion 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);

    2.5.0 SDP erbjuder funktion remoteOfferReceived(id, data) ( createConnection(id); var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data)); pc.createAnswer(function(answer) ( pc.setLocalDescription(answer) )); funktion createConnection(id) (if (peers === odefinierad) (peers = (candidateCache: ); var pc = new PeerConnection(server, optioner); initConnection(pc, id, "svar"); peers.connection = pc; pc.ondatachannel = function(e) ( peers.channel = e.channel; peers.channel.owner = id; bindEvents(peers.channel); ) ) 2.5.1 SDP-svarsfunktion remoteAnswerReceived(id , data) ( var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data) ) 2.5.2 ICE-kandidatfunktion remoteCandidateReceived(id, data) (createConnection(id); var pc = peers.connection; (data)) 2.6. Skickar ett meddelande

    När du klickar på knappen Skicka anropas sendMessage-funktionen. Allt det gör är att gå igenom listan över kamrater och försöka skicka det angivna meddelandet till alla.





    

    2024 gtavrl.ru.