So debuggen Sie WebRTC

Bei Voximplant verwenden wir WebRTC seit seiner Einführung: zuerst als Alternative zu Flash für Sprach- und Videoanrufe und dann als vollständiger Ersatz. Die Technologie hat einen langen und schmerzhaften Entwicklungsweg zurückgelegt. Erst vor kurzem haben alle gängigen Browser damit begonnen, sie zu unterstützen. Es gibt Schwierigkeiten bei der Bildschirmübertragung, mehrere Videostreams, und manchmal stürzt der Browser einfach ab, wenn Sie den Videostream aus- und wieder einschalten. Die gesammelten Erfahrungen ermöglichen es uns, interessante Artikel für Habr zu übersetzen, und heute geben wir das Wort an Lee Sylvester von Xirsys weiter, der über das Debuggen von (Video-) Aufrufen in Chrome, Firefox, Safari und Edge sprechen wird. Das Debuggen von WebRTC ist nicht einfach. Wir haben sogar spezielle Anweisungen zum Entfernen von Protokollen in gängigen Browsern. Und was Lee hat - Sie werden es unter dem Schnitt herausfinden (Spoiler: viel von allem, einschließlich WireShark).


Die dunkle Seite von WebRTC


Während meiner Arbeit bei Xirsys habe ich einige wirklich coole Apps gesehen, die WebRTC verwendeten. Während eine kleine Gruppe von Entwicklern High-Tech-Produkte erstellt, können die meisten Programmierer WebRTC nicht einmal verwenden. Warum? Und alles ist einfach. Es ist kompliziert.

Viele von uns kennen eine typische Webanwendung. Eine solche Anwendung hat einen Client, der Anforderungen sendet, und einen Server, der auf diese Anforderungen reagiert. Ein einfacher, linearer und leicht vorhersehbarer Prozess. Wenn etwas schief geht, wissen wir normalerweise, wo wir uns die Protokolle ansehen müssen und was passieren kann. Aber mit WebRTC ist nicht alles so einfach.

Asynchronität


Wenn Sie jemals eine Multithread-Anwendung geschrieben haben, wissen Sie wahrscheinlich, welche Kopfschmerzen diese Entwicklung verursacht. Flüge, schlechtes Gedächtnis - aber meistens nur Fehler, die schwer zu finden sind.

WebRTC ist asynchroner Natur. Und das ist überhaupt nicht die einfache AJAX-Asynchronität. Um eine Analogie zu ziehen, sind dies mehrere gleichzeitig gestartete AJAX-Anforderungen, die versuchen, Daten auf zwei Computern abzustimmen. Das ist immer noch Unterhaltung.

NAT-Bypass-Minenfeld


Beim Erstellen von Webanwendungen muss etwas entwickelt werden, das auf dem Server ausgeführt wird und auf Anforderungen reagiert. Das Schlimmste, was passieren kann, ist der Port, der in IPTables nicht geöffnet ist. Es wird in 2 Minuten behandelt. Sie können nicht über WebRTC sagen.

Webserver, nicht einmal ihre Software, sondern Hardware, sind Geräte mit öffentlichen IP-Adressen. Sie sind von überall zugänglich. Und WebRTC dient zum Senden und Empfangen von Daten von den Computern der Benutzer. Die haben normalerweise eine IP-Adresse von 192.168. Etwas und brennen nicht mit dem Wunsch, auf Netzwerkanfragen zu antworten.

Die Autoren von WebRTC wissen davon, daher sortiert die Engine verschiedene Verbindungsmethoden, um eine Verbindung zwischen zwei Computern herzustellen, die nicht sehr dafür ausgelegt sind.

Wo soll ich mit dem Debuggen beginnen?


In diesem Artikel spreche ich über die grundlegenden Werkzeuge zur Lösung der beliebtesten Probleme. Aber vorher wollen wir sehen, wie WebRTC normalerweise eine Verbindung herstellt.

Wie WebRTC eine Verbindung herstellt


Alle WebRTC-Verbindungen erfordern ein wenig Hilfe vom Signalisierungsprotokoll. "Wenig Hilfe" ist Ihr eigener Server und Ihr eigenes Protokoll, mit denen der Anrufer mit der Person, die er anruft, kommunizieren kann, bevor er eine Peer-to-Peer-Verbindung herstellt.

WebRTC verwendet das Signalisierungsprotokoll, um Informationen über IP-Adressen, die Fähigkeit zur Erfassung und Wiedergabe von Sprache und Video, die Netzwerktopologie und die übertragenen Daten zu übertragen.

Das häufig verwendete Protokoll ist COMET (oder SIP - Anmerkung des Übersetzers) und Web-Sockets. WebRTC beschränkt Entwickler nicht auf irgendetwas, so dass Sie alles verwenden können, was Sie möchten, zumindest Daten über den Editor übertragen und kopieren und einfügen (in einem der Workshops funktioniert es - wieder ein Übersetzer). Durch die Signalisierung beider Computer können Sie bereits über WebRTC eine Verbindung herstellen.

Angebot und Antwort


WebRTC-Verbindungen verwenden "Angebot" und "Antwort":

  1. Der Initiator der Verbindung erstellt ein "Angebot" und leitet es an die andere Seite weiter.
  2. Die Gegenpartei erhält ein „Angebot“, erstellt eine „Antwort“ und gibt diese zurück.
  3. Der Initiator der Verbindung erhält eine "Antwort".

Das ist theoretisch. In der Praxis sieht der Austausch von Höflichkeiten nicht so einfach aus.

  1. Vor dem Senden von "Angebot" erstellt der Verbindungsinitiator eine Instanz von RTCPeerConnection und empfängt daraus das Textpaket "SDP" (Session Description Protocol) mit rtcPeerConnection.createOffer () . Dieses Paket beschreibt die Fähigkeit, Sprache und Video für den Browser zu empfangen / zu senden.
  2. Der Inhalt des SDP-Pakets wird mithilfe von rtcPeerConnection.setLocalDescription () als "Beschreibung der lokalen Seite der Verbindung" festgelegt .
  3. Das Paket wird an die andere Seite gesendet, wo sein Inhalt mit rtcPeerConnection.setRemoteDescription () als "Beschreibung der anderen Seite der Verbindung" festgelegt wird .
  4. Auf der anderen Seite der Verbindung wird mit rtcPeerConnection.createAnswer () ein eigenes SDP-Paket erstellt. Der Inhalt wird als „Beschreibung der lokalen Seite der Verbindung“ festgelegt.
  5. Das Paket wird an den Verbindungsinitiator weitergeleitet, der seinen Inhalt als "Beschreibung der anderen Seite der Verbindung" festlegt.

Und erst nach all den Aktionen kennen beide Verbindungsparteien die Fähigkeiten des anderen zum Empfangen und Senden von Sprache / Video.

ICE-Kandidaten


Die Fähigkeit, mit Medien zu arbeiten, reicht jedoch nicht aus. Immerhin haben die Vertragsparteien noch nichts über den Zustand des Netzes gesagt.

Sie können sofort herausfinden, welche Video-Codecs der Browser unterstützt und ob sich auf dem Laptop eine Kamera befindet. Es braucht Zeit, um Ihre externe IP-Adresse und die Logik des NAT-Betriebs herauszufinden, und Informationen über den Netzwerkstatus werden ausgetauscht, wenn diese Informationen empfangen werden.

Dank der Trickle ICE-Technologie (nicht von allen Browsern unterstützt - Anmerkung des Übersetzers) kann die Verbindung zwischen zwei WebRTC-Geräten jederzeit hergestellt werden - sobald ein geeigneter „Kandidat“ gefunden wurde.

Der Entwickler muss das Ereignis onicecandidate abonnieren (alles in Kleinbuchstaben!) Und die empfangenen SDP-Pakete an die andere Seite weiterleiten, wo sie von WebRTC mithilfe der addIceCandidate- Methode (und hier Überraschung, Großbuchstabe) übertragen werden müssen. Es funktioniert in beide Richtungen.

Verbindung


WebRTC verwendet Dinge wie STUN (Session Traversal Utilities für NAT) und TURN (Traversal Using Relay um NAT), um eine Verbindung herzustellen. Es klingt beängstigend, aber in Wirklichkeit gibt es nur zwei Netzwerkprotokolle.

STUN Server


Das erste der beiden Protokolle ist etwas komplizierter als der Echoserver. Wenn Verbindungsteilnehmer beschreiben möchten, wie sie eine Verbindung zu ihnen herstellen sollen, benötigen sie ihre öffentliche IP-Adresse. Und höchstwahrscheinlich ist dies nicht die IP-Adresse des Computers. Öffentliche Geräte werden Benutzergeräten selten zugewiesen. Die gesamte NAT-Technologie wurde erfunden, um nicht zu isolieren. Um Ihre öffentliche Adresse weiterhin herauszufinden, sendet der Browser eine Anfrage an den STUN-Server. Beim Durchlaufen von NAT ändert das Netzwerkpaket seine Rücksprungadresse in public. Nachdem der STUN-Server das Paket mit der Anforderung empfangen hat, kopiert er die Rücksprungadresse des Pakets in seine Nutzdaten und sendet das Paket zurück. Beim Durchlaufen von NAT in die entgegengesetzte Richtung verliert das Paket seine öffentliche IP-Adresse, aber eine Kopie dieser Adresse verbleibt in der Nutzlast, wo WebRTC sie lesen kann.


TURN-Server


Der TURN-Server verwendet die STUN-Protokollerweiterung. Dieselben Pakete, Header und eine neue Sache: Befehl . Der Server ist ein Proxy: Beide Clients stellen über den UDP- Zuweisungsport eine Verbindung zu ihm her und übertragen ihre Daten über den Server.

TURN-Server sind so konzipiert, dass der Initiator der Verbindung über mehr Funktionen verfügt als die andere Seite. Dies führt zu einem interessanten Effekt, wenn ein Anruf über einen TURN-Server erfolgreich oder nicht erfolgreich ist, je nachdem, wer wen anruft (denken Sie an alle Skype - Notizübersetzer).


Debuggen


Sie lesen also bis zu diesem Absatz. Wir sind mit dem Übersetzer zufrieden und denken daran, dass es in dem Artikel um das Debuggen von WebRTC geht. Aber all das ist ein notwendiges Minimum, ohne das man nicht einmal anfangen kann. Aber wenn Sie anfangen und kein unmenschliches Glück haben, wird es brechen.

Es wird auf viele verschiedene Arten brechen. Der erste ist der Mangel an Konnektivität. Sie haben sowohl die STUN- als auch die TURN-Servereinstellungen an beide WebRTCs übergeben und ihnen dabei geholfen, Angebote, Antworten und ICE-Kandidaten auszutauschen, aber es gibt weder Video noch Sprache. Wo soll ich anfangen? Bei lokalen Wiedergabeproblemen.

Lokales WebRTC-Debugging


Wie ich oben geschrieben habe, erfolgt die Hauptarbeit von WebRTC auf der Browserseite. STUN- und TURN-Server sind unglaublich einfach, sodass die meisten Probleme in Ihrem JavaScript-Code auftreten, der in zwei Browsern ausgeführt wird. Traurig aber wahr. Auf der anderen Seite, wenn das Interessanteste lokal in Browsern passiert, haben Sie reichlich Gelegenheit zum Debuggen!

Das erste, was Sie überprüfen müssen, ist Ihre Signalisierung. Es ist Ihr Code, der die Konfiguration von Audio mit Video (Angebot, Antwort) und Informationen zu Netzwerkeinstellungen (Eiskandidaten) zwischen Browsern überträgt. Sie müssen überprüfen, welche Pakete gesendet, welche WebRTC empfangen und gesendet wurden:

  • hat die andere Seite der Verbindung ein Angebot erhalten? Hat der Verbindungsinitiator eine Antwort erhalten? Ohne diesen minimalen Austausch von Annehmlichkeiten wird keine Verbindung hergestellt.
  • Hat WebRTC an beiden Enden der Verbindung Pakete mit ICE-Kandidaten weitergeleitet? Haben Sie diese Pakete ausgetauscht und mit addIceCandidate an die andere Seite zurückgegeben ?
  • Wenn beim Paketaustausch alles gut lief, wurde der onaddstream- Ereignishandler aufgerufen und haben Sie das resultierende Objekt in einem HTML-Element installiert, um Video (oder Audio) abzuspielen?

Wenn der Paketaustausch nicht verdächtig ist, können Sie sich mit den Eingeweiden der Sitzung befassen.

Sitzungsbeschreibungsprotokoll


Angebots-, Antwort- und ICE-Kandidatenpakete werden von WebRTC im SDP-Textformat erstellt. Auf den ersten Blick sieht der Inhalt der Pakete beängstigend aus, aber mit ein wenig Vorbereitung können Sie beim Debuggen viel davon profitieren. Wikipedia beschreibt SDP ziemlich gut, aber ich habe eine bessere Beschreibung für Sie gefunden.

Das wichtigste Feld in Kandidaten-ICE-SDP-Paketen ist typ . Für WebRTC kann ein Feld einen von drei Werten haben:

  • typ host;
  • typ srflx;
  • Typ Relais.

Typ Host


Der Hosttyp gibt den ICE-Kandidaten für eine lokale Verbindung an (WebRTC zählt mehrere Kandidaten auf, in der Hoffnung, eine Verbindung herzustellen, es ist nicht im Voraus bekannt, welche sich herausstellen wird - vom Übersetzer notiert). Für eine solche Verbindung ist weder ein STUN- noch ein TURN-Server erforderlich, da Geräte im lokalen Netzwerk häufig Netzwerkverbindungen direkt herstellen können. Beim Debuggen aus dem lokalen Netzwerk müssen Sie nur die Übertragung von Host- Paketen überprüfen und debuggen und sicherstellen, dass die Geräte UDP-Pakete untereinander senden können. Obwohl es Ausnahmen gibt, habe ich in der Praxis Netzwerkkonfigurationen gesehen, bei denen der Browser einen TURN-Server benötigte, um eine Verbindung zu sich selbst herzustellen.

typ srflx


Die Buchstabenkombination „srflx“ steht für „Server Reflexive“ und markiert die Verbindungskandidaten mit einer externen IP-Adresse, wobei ein STUN-Server für die Verbindung ausreicht (mithilfe der NAT-Penetrationstechnologie, die in etwa 80% der Fälle erfolgreich ist, beachten Sie den Übersetzer).

Typ Relais


"Relay" markiert die Verbindung über einen TURN-Server, was fast immer erfolgreich ist. Es ist wichtig zu beachten, dass WebRTC nicht genau drei verschiedene Pakete mit dem Feld "typ" erstellen muss. Wie Kandidaten ausgewählt werden, hängt von der Implementierung von WebRTC in einer bestimmten Browserversion ab.

Testen der Gerätekonnektivität


Google bietet eine spezielle Webanwendung zum Testen von WebRTC-Verbindungen auf Ihrem Gerät. Öffnen Sie die Seite, klicken Sie auf die Schaltfläche "Start". Der JavaScript-Code versucht, mithilfe der Signalisierung, der STUN- und TURN-Server von Google eine Verbindung zum Google-Server herzustellen.

WebRTC-Interna


Sie haben alle Pakete untersucht, den Code überprüft, alles sieht richtig aus, aber es funktioniert nicht? Für solche Fälle hat Google seinem Chrome-Browser einen speziellen Abschnitt zur Verfügung gestellt, in dem die Interna von WebRTC während des Verbindungsaufbaus und einige schöne Grafiken für den Fall einer erfolgreichen Verbindung angezeigt werden. Öffnen Sie zur Verwendung einen speziellen technischen Link im Browser:

chrome://webrtc-internals

Wenn Sie bereits eine Anwendung mit WebRTC geöffnet haben, werden sofort eine Reihe technischer Daten angezeigt. Andernfalls öffnen Sie einfach eine andere Registerkarte und es gibt etwas, das WebRTC verwendet. Auf der Registerkarte werden alle Aufrufe des RTCPeerConnection- Objekts angezeigt , und Sie können in Echtzeit sehen, wie die Verbindung hergestellt wird.

ICE-Setup


Am oberen Rand der Seite befindet sich die ICE-Zeichenfolge, mit der die Verbindung initialisiert wurde. Wenn während seiner Entstehung ein Fehler gemacht wurde, ist dieser sofort sichtbar (durch die "ICE-Linie" verweist der Autor auf die Konfiguration des RTCPeerConnection-Objekts mit einer Liste von STUN- und TURN-Servern (das 'iceServers'-Objekt) - Hinweis des Übersetzers). Vielleicht gibt es keine Liste von Servern? Sie müssen das RTCPeerConnection-Objekt konfigurieren, bevor Sie den ersten Aufruf von createOffer oder createAnswer ausführen .


RTCPeerConnection-Ereignisse


Der nächste interne Abschnitt zeigt die Aufrufe der RTCPeerConnection- Methoden und die vom Objekt empfangenen Ereignisse in chronologischer Reihenfolge. Fehler werden sorgfältig rot hervorgehoben. Bitte beachten Sie, dass das rote addIceCandidateFailed häufig kein Anzeichen für einen Fehler ist und die Verbindung möglicherweise normal hergestellt wird. Wenn die Verbindung erfolgreich ist, ist das letzte Ereignis in der Liste ein iceconnectionstatechange- Ereignis mit dem Wert complete .

Abschnitt 'Statistiken'


Der nächste Abschnitt ist relevant, wenn die Verbindung erfolgreich hergestellt wurde. Es enthält Statistiken über übertragene Daten und Netzwerkverzögerungen. Die zwei interessantesten Optionen sind: ssrc und bweforvideo .

  • ssrc , "Stream Source", markiert jede Ihrer Audio- und Videospuren. Zeigt Statistiken der übertragenen Daten und Parameter an, z. B. die Umlaufzeit .
  • bweforvideo , BandWidth Estimation, zeigt die Breite des verwendeten Netzwerkkanals an.


GetStats-Funktion


Oft können Sie nicht auf die Interna-Seite zugreifen. Zum Beispiel, wenn ein Problem mit Ihrem Benutzer auftritt. In diesem Fall können Sie dieselben Daten abrufen , die auf der internen Seite angezeigt werden, indem Sie die Methode getStats für das RTCPeerConnection- Objekt aufrufen . Diese Methode richtet eine Rückruffunktion ein, die WebRTC jedes Mal aufruft, wenn etwas Interessantes passiert. Die aufgerufene Funktion erhält ein Objekt mit den Feldern, die auf der Interna-Seite angezeigt werden:

 rtcPeerConnection.getStats(function(stats) { document.getElementById("lostpackets").innerText = stats.packetsLost; }); 

Ein weiteres nützliches Tool ist das Ereignis oniceconnectionstatechange eines RTCPeerConnection- Objekts. Der Ereignishandler erhält Informationen zum Verbindungsfortschritt. Mögliche Optionen:

  • neu : WebRTC erwartet Kandidaten von der zweiten Seite der Verbindung, die mit der addIceCandidate- Methode hinzugefügt werden müssen .
  • Überprüfung : WebRTC hat Kandidaten von der zweiten Seite der Verbindung empfangen, vergleicht sie mit lokalen und iteriert über Optionen.
  • verbunden : Ein geeignetes Kandidatenpaar wird ausgewählt und die Verbindung hergestellt. Es ist bemerkenswert, dass die Kandidaten danach gemäß dem Trickle ICE-Protokoll weiter kommen können.
  • abgeschlossen : Alle Kandidaten werden empfangen und die Verbindung hergestellt.
  • getrennt : Die Verbindung wird getrennt . Auf instabilen Kanälen kann sich WebRTC wieder verbinden. Wir überwachen das verbundene Flag.
  • geschlossen : Die Verbindung wird getrennt und WebRTC funktioniert nicht mehr damit.

Wenn die Verbindung im fehlgeschlagenen Zustand beendet wurde, können wir die auf beiden Seiten empfangenen Kandidaten untersuchen und verstehen, warum die Verbindung fehlgeschlagen ist. Wenn beispielsweise eine Seite Host- und srflx-Kandidaten bereitstellte , die andere Seite Host und Relay , die Geräte sich jedoch in unterschiedlichen Netzwerken befanden.

Schwarzes Rechteck statt Video


Oft gibt es eine Situation, in der die Verbindung hergestellt wird, der Ton übertragen wird, aber anstelle des Videos hat einer oder beide Teilnehmer ein schwarzes Rechteck. Meistens geschieht dies, wenn Sie das empfangene Videoobjekt einem HTML-Element zuweisen, bevor die Verbindung in den abgeschlossenen Zustand übergeht.

Wie man einen Zauberstab nach draußen steckt


Zusätzlich zum RTCPeerConnection- Objekt selbst und den vom Browser angezeigten Interna können Sie Tools zur Analyse von Netzwerkpaketen wie Wireshark verwenden. Diese Tools können Pakete verwendeter WebRTC-Protokolle anzeigen. Wireshark zeigt Ihnen beispielsweise den Inhalt von STUN-Paketen im Hauptfenster an, und Sie können sie filtern, indem Sie das Schlüsselwort "stun" in das Filterfeld eingeben:


Was ist in Serverantworten zu beachten? Wenn Sie nur Antworten mit dem Bindungstyp sehen , bedeutet dies, dass nur STUN (externes IP-Gespräch) unterstützt wird und WebRTC nur srflx- Kandidaten anbieten kann . Wenn die Antworten TURN-spezifische Pakete Allocation und CreatePermission enthalten , hat WebRTC die Möglichkeit, eine Verbindung über einen Proxyserver herzustellen. Der Paketanalysator markiert die erfolgreiche und nicht erfolgreiche Zuordnung . Wenn es keinen gibt, der erfolgreich ist, werden höchstwahrscheinlich die falschen Zugriffsparameter auf die TURN-Server (die fast immer mit einem Benutzernamen und einem Kennwort schützen - die Anmerkung des Übersetzers) übergeben.

Wenn das Protokoll ein CreatePermission Success Response- Paket enthält, können wir davon ausgehen, dass mit den Konfigurationen STUN und TURN alles in Ordnung ist. Und wenn es auch ein ChannelBind- Paket gibt, konnte mit hoher Geschwindigkeit eine Verbindung zum TURN-Server hergestellt werden.

Zelluläre Probleme


In meiner Praxis können viele WebRTC-Lösungen, die eine WiFi-Verbindung herstellen, keine Verbindung über 3G / 4G herstellen. Eine auf einem mobilen Gerät gestartete Anwendung ist schwieriger zu debuggen: Wir haben keinen so einfachen Paketanalysator wie Wireshark, und Safari kann keine WebRTC-Interna anzeigen. Die Logik legt nahe, dass das Problem nicht in der Anwendung selbst liegt, sondern in der Mobilfunkkommunikation, wenn die Anwendung über WLAN einwandfrei funktioniert. Wie debuggen? Nehmen Sie einen Laptop und schließen Sie einen 3G-Dongle an. Sie haben also einen Paketanalysator und praktische Protokolle, mit denen Sie die Wurzel aller Probleme in angemessener Zeit finden können.

Schlussfolgerungen


Das Debuggen von WebRTC ist nicht einfach, aber wenn Sie im Internet gut suchen, finden Sie viele Artikel und Beispiele. Wenn Sie im Bereich der Echtzeitkommunikation arbeiten, empfehle ich Ihnen, die RFC-Spezifikationen für die Protokolle STUN , TURN und WebRTC zu lesen. Die Dokumente sind groß, aber die darin enthaltenen Informationen helfen, verlässliche Entscheidungen zu treffen und die Frage zu beantworten, warum es nicht klingelt.

Source: https://habr.com/ru/post/de417869/


All Articles