Zum Hauptinhalt springen

1. Introduction (Einführung)

1. Introduction (Einführung)

Dieses Dokument beschreibt, wie die W3C Web Real-Time Communication (WebRTC) RTCPeerConnection-Schnittstelle [W3C.webrtc] verwendet wird, um die Einrichtung, Verwaltung und den Abbau einer Multimedia-Sitzung zu steuern.

1.1 General Design of JSEP (Allgemeines Design von JSEP)

Die WebRTC-Anrufeinrichtung wurde so konzipiert, dass sie sich auf die Steuerung der Medienebene konzentriert und das Verhalten der Signalisierungsebene so weit wie möglich der Anwendung überlässt. Die Begründung ist, dass verschiedene Anwendungen möglicherweise verschiedene Protokolle bevorzugen, wie z. B. das bestehende SIP-Anrufsignalisierungsprotokoll oder etwas Benutzerdefiniertes für die jeweilige Anwendung, vielleicht für einen neuartigen Anwendungsfall. Bei diesem Ansatz besteht die wichtigste Information, die ausgetauscht werden muss, in der Multimedia-Sitzungsbeschreibung, die die Transport- und Medienkonfigurationsinformationen angibt, die zum Aufbau der Medienebene erforderlich sind.

Unter Berücksichtigung dieser Überlegungen beschreibt dieses Dokument das JavaScript Session Establishment Protocol (JSEP), das eine vollständige Kontrolle der Signalisierungszustandsmaschine von JavaScript aus ermöglicht. Wie oben beschrieben, geht JSEP von einem Modell aus, bei dem eine JavaScript-Anwendung innerhalb einer Laufzeitumgebung ausgeführt wird, die WebRTC-APIs enthält (die "JSEP-Implementierung"). Die JSEP-Implementierung ist fast vollständig vom Kernsignalisierungsfluss getrennt, der stattdessen von JavaScript unter Verwendung von zwei Schnittstellen verarbeitet wird: (1) Übergabe lokaler und entfernter Sitzungsbeschreibungen und (2) Interaktion mit der Interactive Connectivity Establishment (ICE) Zustandsmaschine [RFC8445]. Die Kombination aus JSEP-Implementierung und JavaScript-Anwendung wird in diesem Dokument als "JSEP-Endpunkt" bezeichnet.

In diesem Dokument wird die Verwendung von JSEP so beschrieben, als würde sie immer zwischen zwei JSEP-Endpunkten stattfinden. Beachten Sie jedoch, dass sie in vielen Fällen tatsächlich zwischen einem JSEP-Endpunkt und einer Art Server stattfinden wird, wie z. B. einem Gateway oder einer Multipoint Control Unit (MCU). Diese Unterscheidung ist für den JSEP-Endpunkt unsichtbar; er folgt einfach den Anweisungen, die ihm über die API gegeben werden.

Die Handhabung von Sitzungsbeschreibungen durch JSEP ist einfach und unkompliziert. Wann immer ein Offer/Answer-Austausch benötigt wird, erstellt die initiierende Seite ein Offer durch Aufruf einer createOffer-API. Die Anwendung verwendet dann dieses Offer, um ihre lokale Konfiguration über die setLocalDescription-API einzurichten. Das Offer wird schließlich über seinen bevorzugten Signalisierungsmechanismus (z. B. WebSockets) an die entfernte Seite gesendet; nach Erhalt dieses Offers installiert die entfernte Partei es mithilfe der setRemoteDescription-API.

Um den Offer/Answer-Austausch abzuschließen, verwendet die entfernte Partei die createAnswer-API, um eine geeignete Antwort zu generieren, wendet sie mithilfe der setLocalDescription-API an und sendet die Antwort über den Signalisierungskanal an den Initiator zurück. Wenn der Initiator diese Antwort erhält, installiert er sie mithilfe der setRemoteDescription-API, und die anfängliche Einrichtung ist abgeschlossen. Dieser Prozess kann für zusätzliche Offer/Answer-Austausche wiederholt werden.

In Bezug auf ICE [RFC8445] entkoppelt JSEP die ICE-Zustandsmaschine von der gesamten Signalisierungszustandsmaschine. Die ICE-Zustandsmaschine muss in der JSEP-Implementierung verbleiben, da nur die Implementierung über die erforderlichen Kenntnisse zu Kandidaten und anderen Transportinformationen verfügt. Diese Trennung bietet zusätzliche Flexibilität bei Protokollen, die Sitzungsbeschreibungen vom Transport entkoppeln. Beispielsweise ist in traditionellem SIP jedes Offer oder Answer eigenständig und enthält sowohl die Sitzungsbeschreibungen als auch die Transportinformationen. [RFC8840] erlaubt jedoch die Verwendung von SIP mit Trickle ICE [RFC8838], bei dem die Sitzungsbeschreibung sofort gesendet werden kann und die Transportinformationen gesendet werden können, wenn sie verfügbar sind. Das separate Senden von Transportinformationen kann einen schnelleren ICE- und DTLS-Start ermöglichen, da ICE-Prüfungen beginnen können, sobald Transportinformationen verfügbar sind, anstatt auf alle zu warten. Die Entkopplung von ICE und Signalisierungszustandsmaschinen durch JSEP ermöglicht es, beide Modelle zu unterstützen.

Obwohl es die Signalisierung abstrahiert, erfordert der JSEP-Ansatz, dass die Anwendung den Signalisierungsprozess kennt. Während die Anwendung den Inhalt der Sitzungsbeschreibungen nicht verstehen muss, um einen Anruf einzurichten, muss die Anwendung die richtigen APIs zur richtigen Zeit aufrufen, die Sitzungsbeschreibungen und ICE-Informationen in die definierten Nachrichten ihres gewählten Signalisierungsprotokolls konvertieren und die umgekehrte Konvertierung bei den Nachrichten durchführen, die sie von der anderen Seite erhält.

Eine Möglichkeit, das Leben der Anwendung zu erleichtern, besteht darin, eine JavaScript-Bibliothek bereitzustellen, die diese Komplexität vor dem Entwickler verbirgt; diese Bibliothek würde ein bestimmtes Signalisierungsprotokoll zusammen mit seiner Zustandsmaschine und seinem Serialisierungscode implementieren und dem Anwendungsentwickler eine höhere anrufsorientierte Schnittstelle präsentieren. Es gibt beispielsweise Bibliotheken, die Implementierungen der Signalisierungsprotokolle SIP [RFC3261] und Extensible Messaging and Presence Protocol (XMPP) [RFC6120] auf der JSEP-API bereitstellen. Somit bietet JSEP dem erfahrenen Entwickler mehr Kontrolle, ohne dem Anfängerentwickler zusätzliche Komplexität aufzuzwingen.

1.2 Other Approaches Considered (Betrachtete alternative Ansätze)

Ein Ansatz, der anstelle von JSEP in Betracht gezogen wurde, bestand darin, ein leichtgewichtiges Signalisierungsprotokoll einzuschließen. Anstatt Sitzungsbeschreibungen an die API zu liefern, würde die API Nachrichten von diesem Protokoll produzieren und konsumieren. Während dies eine API auf höherer Ebene bereitstellt, führte es zu mehr Kontrolle der Signalisierung innerhalb der JSEP-Implementierung und zwang sie dazu, Konzepte wie Signalisierungskonflikte (siehe [RFC3264], Abschnitt 4) zu verstehen und zu handhaben.

Ein zweiter in Betracht gezogener, aber nicht gewählter Ansatz bestand darin, die Verwaltung der Mediensteuerungsobjekte von Sitzungsbeschreibungen zu entkoppeln und stattdessen APIs anzubieten, die jede Komponente direkt steuern würden. Dies wurde auf der Grundlage des Arguments abgelehnt, dass die Anforderung, dieses Maß an Komplexität dem Anwendungsprogrammierer offenzulegen, nicht vorteilhaft wäre; es würde (1) zu einer API führen, bei der selbst ein einfaches Beispiel eine erhebliche Menge an Code erfordern würde, um alle erforderlichen Interaktionen zu orchestrieren, und (2) eine große API-Oberfläche schaffen, über die man sich einigen und die dokumentiert werden müsste. Darüber hinaus könnten diese API-Punkte in beliebiger Reihenfolge aufgerufen werden, was zu einem komplexeren Satz von Interaktionen mit dem Mediensubsystem führt als beim JSEP-Ansatz, der festlegt, wie Sitzungsbeschreibungen ausgewertet und angewendet werden sollen.

Eine in Betracht gezogene Variation von JSEP bestand darin, die grundlegende sitzungsbeschreibungsorientierte API beizubehalten, aber den Mechanismus zur Generierung von Offers und Answers aus der JSEP-Implementierung zu entfernen. Anstatt createOffer/createAnswer-Methoden innerhalb der Implementierung bereitzustellen, würde dieser Ansatz stattdessen eine getCapabilities-API offenlegen, die der Anwendung die Informationen liefern würde, die sie benötigt, um ihre eigenen Sitzungsbeschreibungen zu generieren. Dies erhöht die Arbeit, die die Anwendung leisten muss; sie muss wissen, wie man Sitzungsbeschreibungen aus Fähigkeiten generiert, und insbesondere, wie man die richtige Antwort aus einem beliebigen Offer und den unterstützten Fähigkeiten generiert. Während dies sicherlich durch Verwendung einer Bibliothek wie der oben erwähnten gelöst werden könnte, erzwingt es im Grunde die Verwendung dieser Bibliothek selbst für ein einfaches Beispiel. Die Bereitstellung von createOffer/createAnswer vermeidet dieses Problem.

1.3 Contradiction regarding bundle-only "m=" sections (Widerspruch bezüglich bundle-only "m=" Abschnitte)

Seit der Genehmigung der WebRTC-Spezifikationsdokumente ist der IETF eine Inkonsistenz zwischen dem Dokument, das JSEP spezifiziert, und dem Dokument, das BUNDLE spezifiziert (diese RFC bzw. [RFC8843]), bewusst geworden. Anstatt die Veröffentlichung weiter zu verzögern, um zu einer Lösung zu kommen, werden die Dokumente so veröffentlicht, wie sie ursprünglich genehmigt wurden. Die IETF beabsichtigt, die Arbeit an diesen Technologien wieder aufzunehmen, und überarbeitete Versionen dieser Dokumente werden veröffentlicht, sobald eine Lösung verfügbar ist.

Das spezifische Problem betrifft die Handhabung von "m="-Abschnitten, die als bundle-only bezeichnet werden, wie in Abschnitt 4.1.1 dieser RFC erläutert. Derzeit gibt es Unterschiede zwischen JSEP und BUNDLE sowie zwischen diesen Spezifikationen und bestehenden Browser-Implementierungen:

  • JSEP schreibt vor, dass diese "m="-Abschnitte Port Null verwenden und ein "a=bundle-only"-Attribut in initialen Offers hinzufügen sollten, aber nicht in Answers oder nachfolgenden Offers.

  • BUNDLE schreibt vor, dass diese "m="-Abschnitte wie im vorherigen Punkt beschrieben gekennzeichnet werden sollten, aber in allen Offers und Answers.

  • Die meisten aktuellen Browser kennzeichnen keine "m="-Abschnitte mit Port Null und verwenden stattdessen denselben Port für alle gebündelten "m="-Abschnitte; einige andere folgen dem JSEP-Verhalten.