Millionen Videoanrufe pro Tag oder "Call Mom!"

Aus Sicht des Benutzers sehen die Anrufdienste ziemlich einfach aus: Sie gehen zu einem anderen Benutzer auf die Seite, Sie rufen an, er nimmt den Hörer ab, Sie sprechen mit ihm. Draußen scheint alles einfach zu sein, aber nur wenige wissen, wie man einen solchen Service macht. Aber Alexander Tobol ( alatobol ) weiß nicht nur Bescheid, sondern teilt auch gerne seine Erfahrungen.



Weiter die Textversion des Berichts über HighLoad ++ Sibirien, aus der Sie lernen werden:

  • wie Videoanrufdienste unter der Haube funktionieren;
  • Wie schön es ist, NAT zu durchbrechen - dies wird für Spielspezialisten interessant sein, die eine Peer-to-Peer-Verbindung benötigen.
  • wie WebRTC funktioniert, welche Protokolle es enthält;
  • Wie kann ich WebRTC über BigData optimieren?


Über den Sprecher: Alexander Tobol leitet die Entwicklung der Video- und Tape-Plattformen bei ok.ru.

Videoanrufverlauf


Das erste Videoanrufgerät erschien 1960, es wurde als Picherphone bezeichnet, verwendete dedizierte Netzwerke und war extrem teuer. Im Jahr 2006 fügte Skype seiner Anwendung Videoanrufe hinzu. Im Jahr 2010 unterstützte Flash das RTMFP-Protokoll, und wir von Odnoklassniki starteten Flash-Videoanrufe. Im Jahr 2016 hat Chrome die Unterstützung von Flash eingestellt, und im August 2017 haben wir Anrufe mit der neuen Technologie neu gestartet, über die ich heute sprechen werde. Nach Abschluss des Dienstes erhielten wir für weitere sechs Monate einen deutlichen Anstieg der erfolgreich abgeschlossenen Anrufe. In letzter Zeit haben wir auch Masken in Anrufen.


Architektur und TK


Da wir in einem sozialen Netzwerk arbeiten, haben wir keine technischen Aufgaben und wissen nicht, was TK ist. Normalerweise passt die ganze Idee auf eine Seite und sieht ungefähr so ​​aus.


Der Benutzer möchte andere Benutzer über eine Web- oder iOS / Android-Anwendung anrufen. Ein anderer Benutzer kann mehrere Geräte haben. Der Anruf kommt an alle Geräte, der Benutzer nimmt das Telefon auf einem von ihnen ab, sie sprechen. Alles ist einfach.

Technische Eigenschaften


Um einen qualitativ hochwertigen Anrufservice durchführen zu können, müssen wir verstehen, welche Merkmale wir verfolgen möchten. Wir haben uns entschlossen, zunächst zu suchen, was den Benutzer am meisten stört.

Der Benutzer ist definitiv verärgert, wenn er den Hörer abhebt und warten muss, bis die Verbindung hergestellt ist.


Der Benutzer ist verärgert, wenn die Anrufqualität schlecht ist - etwas wird unterbrochen, das Video wird gestreut, der Ton sprudelt.


Vor allem aber ärgert sich der Benutzer über die Verzögerung bei Anrufen. Die Latenz ist eines der wichtigen Merkmale von Anrufen. Bei einer Latenz in einem Gespräch in der Größenordnung von 5 Sekunden ist es absolut unmöglich, einen Dialog zu führen.


Wir haben für uns akzeptable Eigenschaften festgestellt:

  • Start - wir haben beschlossen, dass es gut ist, den Anruf in einer Sekunde zu starten. Das heißt, Das Verbinden, nachdem der Benutzer geantwortet hat, sollte nicht länger als 1 Sekunde dauern.
  • Qualität ist ein sehr subjektiver Indikator. Sie können beispielsweise das Signal-Rausch-Verhältnis (SNR) messen, es fehlen jedoch noch Frames und andere Artefakte. Wir haben die Qualität eher subjektiv gemessen und dann die Zufriedenheit der Benutzer bewertet.
  • Die Latenz sollte weniger als 0,5 Sekunden betragen . Wenn die Latenz länger als 0,5 Sekunden ist, hören Sie bereits Verzögerungen und beginnen sich gegenseitig zu unterbrechen.



Polycom ist ein Konferenzsystem, das in unseren Büros installiert wird. Wir haben durchschnittliche Polycom-Latenzen in der Größenordnung von 1,3 Sekunden. Mit einer solchen Verzögerung verstehen Sie sich nicht immer. Wenn sich die Verzögerung auf 2 Sekunden erhöht, ist kein Dialog möglich.


Da wir die Plattform bereits gestartet hatten, erwarteten wir ungefähr eine Million Anrufe pro Tag. Dies sind tausend Anrufe parallel. Wenn alle Anrufe über den Server gestartet werden, werden pro Anruf tausend Megabit-Anrufe getätigt. Dies ist nur 1 Gigabit / Sek. Ein Eisenserver wird ausreichen.

Internet gegen TTX


Was kann Sie daran hindern, solch coole Funktionen zu erreichen? Das Internet!


Im Internet gibt es solche Dinge wie Roundtrip Time (RTT), die nicht überwunden werden können, es gibt eine variable Bandbreite, es gibt NAT.

Zuvor haben wir die Übertragungsgeschwindigkeit in den Netzen unserer Benutzer gemessen.


Wir haben es nach Art der Verbindung aufgeschlüsselt, die durchschnittliche RTT, den Paketverlust und die Geschwindigkeit untersucht und beschlossen, die Anrufe anhand der Durchschnittswerte jedes dieser Netzwerke zu testen.


Es gibt andere Probleme im Internet:

  • Paketverlust - Wir haben einen zufälligen Paketverlust von 0,6% gemessen (wir berücksichtigen den Paketverlust bei Überlastung bei einer übermäßigen Anzahl von Paketen nicht).
  • Neuordnung - Sie senden Pakete in derselben Reihenfolge und das Netzwerk sortiert sie neu.
  • Jitter - Senden Sie in einem bestimmten Intervall einen Video- oder Audiostream, und Pakete werden auf der Clientseite zu Bündeln zusammengefasst, z. B. aufgrund der Pufferung auf Netzwerkgeräten.
  • NAT - Es stellte sich heraus, dass mehr als 97% der Benutzer hinter NAT stehen. Wir werden darüber sprechen, warum, was und wie.



Betrachten Sie die oben aufgeführten Netzwerkeinstellungen anhand eines einfachen Beispiels.

Ich habe die Website der Staatlichen Universität Nowosibirsk von meinem Büro aus durchgesehen und so einen seltsamen Ping bekommen.


Der durchschnittliche Jitter in diesem Beispiel beträgt 30 ms, dh das durchschnittliche Intervall zwischen benachbarten Ping-Zeiten beträgt etwa 30 ms und der durchschnittliche Ping beträgt 105 ms.

Was ist bei Anrufen wichtig, warum werden wir für p2p kämpfen?


Wenn es uns gelingt, eine P2P-Verbindung zwischen unseren Benutzern herzustellen, die versuchen, in St. Petersburg miteinander zu kommunizieren, anstatt über einen Server in Nowosibirsk, sparen wir natürlich etwa 100 ms Hin- und Rückfahrt und Datenverkehr zu diesem Dienst.

Daher widmet sich der größte Teil des Artikels der Herstellung von gutem P2P.

Geschichte oder Erbe


Wie gesagt, wir haben seit 2010 einen Anrufdienst und jetzt haben wir ihn neu gestartet.


Im Jahr 2006, als Skype startete, kaufte Flash Amicima, das RTMFP herstellte. Flash hatte bereits RTMP, das im Prinzip für Anrufe verwendet werden kann, und es wird häufig für das Streaming verwendet. Flash öffnete später die RTMP-Spezifikation. Ich frage mich, warum sie RTMFP brauchten? Im Jahr 2010 haben wir RTMFP verwendet.

Vergleichen Sie die Anforderungen für Anrufprotokolle und echte Streaming-Protokolle und sehen Sie, wo sich diese Grenze befindet.


RTMP ist eher ein Video-Streaming-Protokoll. Es verwendet TCP, es hat kumulative Verzögerung. Wenn Sie eine gute Internetverbindung haben, funktionieren Anrufe bei RTMP.

Das RTMFP-Protokoll ist trotz des Unterschieds in nur einem Buchstaben das UDP-Protokoll. Es ist frei von Pufferproblemen - solchen, die auf TCP sind; Es wird die Head-of-Line-Blockierung vorenthalten. In diesem Fall haben Sie ein Paket verloren, und TCP gibt die folgenden Pakete erst zurück, wenn es Zeit ist, das verlorene Paket erneut zu senden. RTMFP war in der Lage, NAT zu verarbeiten, und die IP-Adresse der Clients wurde geändert. Aus diesem Grund haben wir 2010 das Web auf RTMFP gestartet.


Erst 2011 erschien dann der erste Entwurf des WebRTC, der noch nicht voll funktionsfähig war. Im Jahr 2012 haben wir begonnen, Anrufe unter iOS / Android zu unterstützen, dann ist etwas anderes passiert, und im Jahr 2016 hat Chrome die Unterstützung von Flash eingestellt. Wir mussten etwas tun.


Wir haben uns alle VoIP-Protokolle angesehen: Wie immer, um etwas zu tun, schauen wir uns zunächst die Wettbewerber an.

Konkurrenten oder wo ich anfangen soll


Wir haben die beliebtesten Konkurrenten ausgewählt: Skype, WhatsApp, Google Duo (ähnlich wie Hangouts) und ICQ.

Zunächst haben wir die Verzögerung gemessen.


Es ist einfach zu tun. Oben ist ein Foto, auf dem:

  • Stoppuhr (siehe Telefon oben links), die die Uhrzeit anzeigt (03:08).
  • Das nahe gelegene Telefon tätigt einen Anruf und nimmt das erste Telefon als Video. Von dem Moment an, als das Bild in die Kamera des Telefons gelangt ist und Sie es gesehen haben, dauerte es ungefähr 100 ms.
  • Ein Anruf an ein anderes Telefon (weiß) und noch einmal. Hier beträgt die Verzögerung bei Google Duo ca. 310 ms.

Ich werde noch nicht alle Karten aufdecken, aber wir haben sichergestellt, dass diese Geräte keine P2P-Verbindungen herstellen können. Natürlich wurden die Messungen in verschiedenen Netzwerken durchgeführt, und dies ist nur ein Beispiel.


Skype unterbricht immer noch ein wenig. Es stellte sich heraus, dass bei Skype die Verzögerung 1,1 s beträgt, falls p2p nicht verbunden werden kann.

Unsere Testumgebung war kompliziert. Wir haben unter verschiedenen Bedingungen (EDGE, 3G, LTE, WiFi) getestet, berücksichtigt, dass die Kanäle asymmetrisch sind, und ich gebe die Durchschnittswerte aller Messungen an.


Um den Akkuverbrauch, die Prozessorlast und alles andere abzuschätzen, haben wir beschlossen, dass Sie die Telefontemperatur einfach mit einem Pyrometer messen und davon ausgehen können, dass dies eine durchschnittliche Belastung der GPU des Telefons pro Prozessor und Akku ist. Im Prinzip ist es sehr unangenehm, ein heißes Telefon an Ihr Ohr zu bringen und es sogar in Ihren Händen zu halten. Es scheint dem Benutzer, dass die Anwendung jetzt ihren gesamten Akku verbraucht.


Das Ergebnis ist:

  • Die langsamsten Verzögerungen waren ICQ und Skype und die schnellsten - Telegramm. Dies ist kein vollständig korrekter Vergleich, da Telegramm keine Videoanrufe hat, aber eine minimale Audio-Latenz aufweist. WhatsApp (ca. 200 ms) und Hangouts - 390 ms funktionieren hervorragend.
  • Nach Temperatur isst Telegramm am wenigsten ohne Video und Skype am meisten.
  • In Bezug auf die Antwortzeit stellt Telegram die Verbindung für die längste Zeit und die schnellste WhatsApp und Google Duo her.

Großartig, wir haben einige Metriken!


Wir haben die Qualität von Video und Sprache in verschiedenen Netzwerken getestet, mit verschiedenen Tropfen und allem anderen. Infolgedessen kamen wir zu dem Schluss, dass das Video mit der höchsten Qualität bei Google Duo und die Stimme bei Skype verfügbar ist. Dies ist jedoch in „schlechten“ Netzwerken der Fall, wenn bereits Verzerrungen vorliegen. Im Allgemeinen arbeitet jeder ungefähr mittelmäßig. WhatsApp hat das unscharfeste Bild.

Mal sehen, worauf es ankommt.


Skype verfügt über ein eigenes proprietäres Protokoll, und alle anderen verwenden entweder eine Modifikation von WebRTC oder im Allgemeinen direkt WebRTC. Hangouts, Google Duo, WhatsApp und Facebook Messenger können mit dem Web arbeiten, und alle haben WebRTC unter der Haube. Sie sind alle so unterschiedlich, mit unterschiedlichen Eigenschaften und sie haben alle ein WebRTC! Sie müssen es also richtig kochen können. Außerdem gibt es Telegramm, für das einige Teile von WebRTC für den Audioteil verantwortlich sind, und ICQ, das WebRTC lange Zeit gabelte und seinen eigenen Weg weiterentwickelte.

WebRTC Architektur




WebRTC impliziert das Vorhandensein eines Signalisierungsservers, eines Vermittlers zwischen Clients, der zum Austausch von Nachrichten während des Aufbaus einer P2P-Verbindung zwischen ihnen verwendet wird. Nach dem Herstellen einer direkten Verbindung beginnen Clients, Mediendaten miteinander auszutauschen.

WebRTC Demo


Beginnen wir mit einer einfachen Demo. Es gibt 5 einfache Schritte, um eine WebRTC-Verbindung herzustellen.

Detaillierter Beispielcode
1. // Step #1: Getting local video stream and initializing a peer connection with it (both caller and callee) 2. 3. var localStream = null; 4. var localVideo = document.getElementById('localVideo'); 5. 6. navigator 7. .mediaDevices 8. .getUserMedia({ audio: true, video: true }) 9. .then(stream => { 10. localVideo.srcObject = stream; 11. localStream = stream; 12. }); 13. 14. var pc = new RTCPeerConnection({ iceServers: [...] }); 15. 16. localStream 17. .getTracks() 18. .forEach(track => pc.addTrack(track, localStream)); 19. 20. // Step #2: Creating SDP offer (caller) 21. 22. pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true }) 23. .then(offer => signaling.send('offer', offer)); 24. 25. // Step #3: Handling SDP offer and sending SDP answer (callee) 26. 27. signaling.on('offer', offer => { 28. pc.setRemoteDescription(offer) 29. .then(() => pc.createAnswer()) 30. .then(answer => signaling.send('answer', answer)) 31. }); 32. 33. // Step #4: Handling SDP answer (calleer) 34. 35. signaling.on('answer', answer => pc.setRemoteDescription(answer)); 36. 37. // Step #5: Exchanging ICE candidates 38. 39. pc.onicecandidate = event => signaling.send('candidate', event.candidate); 40. 41. signaling.on('candidate', candidate => pc.addIceCandidate(candidate)); 42. 43. // Step #6: Getting remote video stream (both caller and callee) 44. 45. var remoteVideo = document.getElementById('remoteVideo'); 46. 47. pc.onaddstream = event => remoteVideo.srcObject = event.streams[0]; 


Es heißt folgendes:

  1. Nehmen Sie ein Video auf und stellen Sie eine Peer-Verbindung her. Übertragen Sie eine Art IceServer (es ist nicht sofort klar, um was es sich handelt).
  2. Erstellen Sie ein SDP-Angebot und senden Sie es an die Signalisierung. Die Signalisierung von WebRTC wird in keiner Weise für Sie implementiert.
  3. Dann müssen Sie einen Wrapper für denjenigen erstellen, der von der Signalisierung stammt, und dies ist auch nicht Teil von WebRTC.
  4. Tauschen Sie einige Kandidaten weiter aus.
  5. Holen Sie sich endlich den Remote-Videostream.

Lassen Sie uns herausfinden, was dort passiert und was wir selbst umsetzen müssen.


Wir betrachten das Bild von unten nach oben. Es gibt eine WebRTC-Bibliothek, die bereits in den Browser integriert ist und von Chrome, Firefox usw. unterstützt wird. Sie können sie unter Android / iOS erstellen und über die API und SDP (Session Description Protocol) mit ihr kommunizieren, die die Sitzung selbst beschreibt. Im Folgenden werde ich Ihnen sagen, was darin enthalten ist. Um diese Bibliothek in Ihrer Anwendung zu verwenden, müssen Sie durch Signalisierung eine Verbindung zwischen Teilnehmern herstellen. Die Signalisierung ist auch Ihr Dienst, den Sie selbst schreiben müssen. WebRTC bietet sie nicht an.

Weiter im Artikel werden wir das Netzwerk in der richtigen Reihenfolge diskutieren, dann Video / Audio, und am Ende werden wir unsere Signalisierung schreiben.

WebRTC-Netzwerk oder p2p (eigentlich c2s2c)


Das Einrichten einer P2P-Verbindung scheint ziemlich einfach zu sein.


Wir haben Alice und Bob, die eine P2P-Verbindung herstellen möchten. Sie nehmen ihre IP-Adressen, haben einen Signalisierungsserver, mit dem sie beide verbunden sind, und über den sie diese Adressen austauschen können. Sie tauschen Adressen aus und oh! Sie haben die gleichen Adressen, etwas ist schief gelaufen!


Tatsächlich sitzen beide Benutzer höchstwahrscheinlich hinter WLAN-Routern, und dies sind ihre lokalen grauen IP-Adressen. Der Router bietet ihnen eine Funktion wie Network Address Translation (NAT). Wie arbeitet sie?


Sie haben ein graues Subnetz und eine externe IP-Adresse. Sie senden ein Paket von Ihrer grauen Adresse ins Internet, NAT ersetzt Ihre graue Adresse durch Weiß und merkt sich die Zuordnung: von welchem ​​Port es gesendet wurde, an welchen Benutzer und mit welchem ​​Port es übereinstimmt. Wenn das Rückpaket ankommt, wird es durch diese Zuordnung aufgelöst und an den Absender gesendet. Alles ist einfach.

Unten ist eine Illustration, wie es bei mir aussieht.


Dies ist meine interne IP-Adresse und die Adresse des Routers (übrigens auch grau). Wenn Sie die Route verfolgen und sehen, sehen wir meinen WLAN-Router: ein Paket grauer Anbieteradressen und eine externe weiße IP. Tatsächlich werde ich also zwei NATs haben: einen, auf dem ich über WLAN bin, und einen anderen vom Anbieter, es sei denn, ich habe mir natürlich eine dedizierte externe IP-Adresse gekauft.

NAT ist so beliebt, weil:

  • Viele IPv4s fehlen noch und es gibt nicht genügend Adressen.
  • NAT scheint das Netzwerk zu schützen;
  • Dies ist eine Standardfunktion des Routers: Stellen Sie eine Verbindung zu Wi-Fi her, es gibt NAT genau dort, es funktioniert.

Daher sitzen nur 3% der Benutzer mit einer externen IP, während der Rest über NAT läuft.

Mit NAT können Sie sicher zu beliebigen weißen Adressen wechseln. Aber wenn Sie nirgendwo hingegangen sind, kann niemand zu Ihnen kommen.


Das Herstellen einer P2P-Verbindung ist ein Problem. Tatsächlich können Alice und Bob keine Pakete aneinander senden, wenn sie beide hinter NAT stehen.

WebRTC verfügt über ein STUN-Protokoll , um dieses Problem zu lösen. Es wird vorgeschlagen, einen STUN-Server bereitzustellen. Dann stellt Alice eine Verbindung zum STUN-Server her, erhält ihre IP-Adresse und sendet sie per Signal an Bob. Bob erhält auch seine IP-Adresse und sendet sie an Alice. Sie senden Pakete aufeinander zu und durchbrechen so NAT.


Frage : Alice hat einen bestimmten Port geöffnet, NAT / Firewall wurde bereits auf diesen Port durchbrochen, und Bob ist offen. Sie kennen die Adressen der anderen. Alice versucht das Paket an Bob zu senden, er sendet das Paket an Alice. Glaubst du, sie können reden oder nicht?

In der Tat haben Sie in jedem Fall Recht, das Ergebnis hängt von der Art des NAT-Paares ab, über das Benutzer verfügen.


Übersetzung der Netzwerkadresse


Es gibt 4 Arten von NAT:

  1. Vollkegel NAT;
  2. Eingeschränkter Kegel NAT;
  3. Port eingeschränkter Kegel NAT;
  4. Symmetrisches NAT

In der Basisversion sendet Alice ein Paket an den STUN-Server, sie öffnet einen Port. Bob erfährt irgendwie von ihrem Port und sendet ein Rückpaket. Wenn dies Full Cone NAT ist - das einfachste, das nur den externen Port dem internen Port zuordnet, kann Bob Alice sofort ein Paket senden, eine Verbindung herstellen und sie werden sprechen.


Unten ist das Interaktionsschema: Alice von einem Port sendet ein Paket an den STUN-Port, STUN antwortet ihr mit ihrer externen Adresse. STUN kann von jeder Adresse aus antworten. Wenn es sich um Vollkegel-NAT handelt, wird NAT weiterhin durchgestrichen, und Bob kann auf dieselbe Adresse antworten.


Im Fall von Restricted Cone NAT sind die Dinge etwas komplizierter. Es merkt sich nicht nur den Port, von dem aus Sie die interne Adresse zuordnen müssen, sondern auch die externe Adresse, zu der Sie gegangen sind. Das heißt, wenn Sie nur eine Verbindung zum IP STUN-Server hergestellt haben, kann Ihnen niemand im Netzwerk antworten, und dann erreicht Bobs Paket nicht.


Wie wird dieses Problem gelöst? In einem einfachen Schema (siehe Abbildung unten) wie folgt: Alice sendet ein Paket an STUN, er antwortet ihr mit ihrer IP. STUN kann von jedem Port aus darauf reagieren, solange es sich um Restricted Cone NAT handelt. Bob kann Alice nicht antworten, weil er eine andere Adresse hat. Alice antwortet mit einem Paket und kennt Bobs IP-Adresse. Sie öffnet NAT für Bob, Bob antwortet ihr. Hurra, sie haben geredet.


Eine etwas kompliziertere Option ist Port Restricted Cone NAT . Trotzdem sollte nur STUN genau von dem Port aus reagieren, auf den zugegriffen wurde. Alles wird auch funktionieren.

Das schädlichste ist Symmetric NAT .


Zunächst funktioniert alles genauso - Alice sendet das Paket an den STUN-Server, es antwortet über denselben Port. Bob kann Alice nicht antworten, aber sie sendet das Paket an Bob. Und hier, obwohl Alice ein Paket an Port 4444 sendet, weist ihr das Mapping einen neuen Port zu. Symmetrisches NAT unterscheidet sich darin, dass beim Herstellen jeder neuen Verbindung jedes Mal, wenn ein neuer Port am Router ausgegeben wird. Dementsprechend schlägt Bob in dem Port, von dem Alice zu STUN gegangen ist, und sie können keine Verbindung herstellen.

In der entgegengesetzten Richtung, wenn Bob eine offene IP-Adresse hat, kann Alice einfach zu ihm kommen und sie werden eine Verbindung herstellen.

Alle Optionen sind in einer Tabelle unten zusammengefasst.


Es zeigt, dass fast alles möglich ist, außer wenn wir versuchen, Verbindungen über Symmetric NAT mit Port Restricted Cone NAT oder Symmetric NAT am anderen Ende herzustellen.


Wie wir herausgefunden haben, ist p2p für uns in Bezug auf die Latenz von unschätzbarem Wert. Wenn es jedoch nicht möglich war, es zu installieren, bietet uns WebRTC einen TURN-Server an. Als wir feststellten, dass p2p nicht installiert werden kann, können wir einfach eine Verbindung zu TURN herstellen, wodurch der gesamte Datenverkehr übertragen wird. Gleichzeitig zahlen Sie jedoch für den Datenverkehr, und Benutzer können einige zusätzliche Verzögerungen haben.

Übe


Google hat kostenlose STUN-Server. Sie können sie in die Bibliothek stellen, es wird funktionieren.

TURN-Server verfügen über Anmeldeinformationen (Login und Passwort). Höchstwahrscheinlich müssen Sie Ihre eigenen erhöhen, es ist ziemlich schwierig, frei zu finden.

Beispiele für kostenlose STUN-Server von Google:

  • stun: stun.l.google.com: 19302
  • stun: stun1.l.google.com: 19302
  • stun: stun2.l.google.com: 19302
  • stun: stun3.l.google.com: 19302

Und ein kostenloser TURN-Server mit Passwörtern: URL: 'Turn: 192.158.29.39: 3478? Transport = udp', Berechtigungsnachweis: 'JZEOEt2V3Qb0y27GRntt2u2PAYA =', Benutzername: '28224511: 1379330808'.

Wir benutzen Coturn .


Infolgedessen werden 34% des Datenverkehrs über die P2P-Verbindung übertragen, alles andere wird über den TURN-Server übertragen.

Was ist sonst noch im STUN-Protokoll interessant?


Mit STUN können Sie den NAT-Typ bestimmen.


Schiebelink

Wenn Sie ein Paket senden, können Sie angeben, dass Sie eine Antwort von demselben Port erhalten möchten, oder STUN bitten, von einem anderen Port, von einer anderen IP oder sogar von einer anderen IP und einem anderen Port zu antworten. Somit können Sie für 4 Abfragen an den STUN-Server den NAT-Typ bestimmen .


Wir haben die NAT-Typen gezählt und festgestellt, dass fast alle Benutzer entweder symmetrisches NAT oder portbeschränktes Kegel-NAT haben. Daher stellt sich heraus, dass nur ein Drittel der Benutzer eine P2P-Verbindung herstellen kann.

Sie fragen sich vielleicht, warum ich Ihnen das alles erzähle, wenn Sie den STUN einfach von Google nehmen und in WebRTC einfügen könnten, und es scheint, als würde alles funktionieren.

Weil Sie den NAT-Typ tatsächlich selbst bestimmen können.


Dies ist ein Link zu einer Java-Anwendung, die nichts Schwieriges tut: Sie pingt nur verschiedene Ports und verschiedene STUN-Server an und überprüft, welchen Port sie am Ende sieht. Wenn Sie Open Full Cone NAT haben, hat der STUN-Server denselben Port. Mit Restricted Cone NAT haben Sie unterschiedliche Ports für jede STUN-Anforderung.


Mit Symmetric NAT sieht es in meinem Büro so aus. Es gibt völlig unterschiedliche Ports.

Manchmal gibt es jedoch ein interessantes Muster, bei dem die Portnummer für jede Verbindung um eins erhöht wird.


Das heißt, viele NATs sind so konfiguriert, dass sie den Port um eine Konstante erhöhen oder verringern. Diese Konstante kann gefunden werden und somit Symmetric NAT durchbrechen.


So durchbrechen wir NAT - wir gehen zu einem STUN-Server, zu einem anderen, schauen uns den Unterschied an, vergleichen und versuchen erneut, unseren Port bereits mit diesem Inkrement oder Dekrement zu versehen. Das heißt, Alice versucht, Bob ihren Port zu geben, der bereits auf eine Konstante eingestellt ist, und weiß, dass es beim nächsten Mal genau das sein wird.


So konnten wir weitere 12% Peer-to-Peer schweißen.

Tatsächlich verhalten sich externe Router mit derselben IP manchmal gleich. Wenn Sie also Statistiken erfassen und Symmetric NAT eine Funktion des Anbieters und keine Funktion des WLAN-Routers des Benutzers ist, kann das Delta vorhergesagt werden. Senden Sie es sofort an den Benutzer, damit er es verwendet und nicht zu viel Zeit damit verbringt, es zu bestimmen.

CDN-Relay oder was zu tun ist, wenn Sie keine P2P-Verbindung herstellen konnten


Wenn wir weiterhin den TURN-Server verwenden und nicht in p2p, sondern im Real-Modus arbeiten und den gesamten Datenverkehr über den Server leiten, können wir weiterhin ein CDN hinzufügen. Es sei denn natürlich, Sie haben einen Spielplatz. Wir haben unsere eigenen CDN-Sites, daher war es für uns ganz einfach. Es musste jedoch festgestellt werden, wo es besser ist, eine Person zu senden: zu einer CDN-Site oder beispielsweise zu einem Kanal nach Moskau. Dies ist keine sehr triviale Aufgabe, also haben wir Folgendes getan:

  1. Versehentlich an einige Benutzer der Moskauer Website ausgegeben, einige - entfernt.
  2. Wir haben Statistiken über die IP des Benutzers, auf den Servern und über die Eigenschaften des Netzwerks gesammelt.
  3. Mit maxMind haben wir die Subnetze gruppiert, die Statistiken überprüft und anhand der IP ermittelt, welcher Benutzer den nächstgelegenen TURN-Server für die Verbindung hatte.



In Nowosibirsk gibt es ein CDN. Wenn in Moskau alles für Sie funktioniert, beträgt das 99. Perzentil von RTT 1,3 Sekunden. Durch CDN funktioniert alles viel schneller (0,4 Sekunden).

Ist es immer besser, eine P2P-Verbindung zu verwenden und keinen Server zu verwenden? Ein interessantes Beispiel sind die beiden Krasnojarsker Anbieter Optibyte und Mobra (Namen haben sich möglicherweise geändert). Aus irgendeinem Grund ist die Verbindung zwischen ihnen auf p2p viel schlechter als über MSK. Wahrscheinlich sind sie nicht miteinander befreundet.


Wir haben alle diese Fälle analysiert, zufällig Benutzer an p2p oder über MSK gesendet, Statistiken gesammelt und Vorhersagen erstellt. Wir wissen, dass Statistiken aktualisiert werden müssen. Daher stellen wir für einige Benutzer spezielle Verbindungen her, um zu überprüfen, ob sich in den Netzwerken etwas geändert hat.

Wir haben so einfache Eigenschaften wie Rundzeit, Paketverlust und Bandbreite gemessen - es bleibt zu lernen, wie man sie richtig vergleicht.


Wie kann man verstehen, was besser ist: 2 Mbit / s Internet, 400 ms RTT und 5% Paketverlust oder 100 Kbit / s, 100 ms Verzögerung und geringer Paketverlust?

Es gibt keine genaue Antwort, die Bewertung der Videoanrufqualität ist sehr subjektiv. Daher haben wir die Benutzer nach dem Ende des Aufrufs gebeten, die Qualität der Sternchen zu bewerten und die Konstanten entsprechend den Ergebnissen festzulegen. Es stellte sich heraus, dass beispielsweise die RTT weniger als 300 ms beträgt - es spielt keine Rolle mehr, die Bitrate ist wichtiger.

Höhere Benutzerbewertungen für Android und iOS. Es ist zu sehen, dass iOS-Benutzer eher eine Einheit und häufiger fünf einsetzen. Ich weiß nicht, warum wahrscheinlich die Besonderheiten der Plattform. Aber wir haben die Konstanten entlang gezogen, so dass wir, wie es uns scheint, gut waren.

Zurück zu unserem Entwurf für den Artikel, diskutieren wir immer noch das Netzwerk.

Wie sieht der Verbindungsaufbau aus?


Wir senden STUN- und TURN-Server an PeerConnection (), eine Verbindung wird hergestellt. Alice findet ihre IP heraus und sendet sie an die Signalisierung. Bob erfährt von Alices IP. Alice bekommt Bobs IP. Sie tauschen Pakete aus, durchbrechen möglicherweise NAT, stellen möglicherweise TURN ein und kommunizieren.


In den 5 Schritten zum Herstellen der Verbindung, die wir zuvor besprochen haben, haben wir die Server herausgefunden, herausgefunden, wo sie erhältlich sind, und dass ICE-Kandidaten externe IP-Adressen sind, die wir durch Signalisierung austauschen. Es kann auch versucht werden, interne IP-Adressen von Clients zu durchbrechen, wenn sie sich in Reichweite eines Wi-Fi befinden.

Fahren wir mit dem Teil des Videos fort.

Video und Audio


WebRTC unterstützt eine Reihe von Video- und Audio-Codecs, Sie können dort jedoch Ihren eigenen Codec hinzufügen. Grundsätzlich unterstützt von H.264 und VP8 für Video . VP8 ist ein Software-Codec und verbraucht daher viel Batterie. H.264 ist nicht auf allen Geräten verfügbar (normalerweise nativ), daher ist die Standardpriorität VP8.

Innerhalb von SDP (Session Description Protocol) gibt es eine Codec-Aushandlung: Wenn ein Client eine Liste seiner Codecs sendet, sendet der andere eine eigene mit Priorität und sie vereinbaren, welche Codecs für die Kommunikation verwendet werden. Falls gewünscht, können Sie die Priorität der VP8- und H.264-Codecs ändern. Aus diesem Grund können Sie auf einigen Geräten, auf denen 264 nativ ist, Batterie sparen. Hier ist ein Beispiel, wie dies getan werden kann. Wir haben dies getan, es schien uns, dass sich die Benutzer nicht über die Qualität beschwerten, aber gleichzeitig wurde die Batterieladung viel weniger verbraucht.

Für Audio hat WebRTC OPUS oder G711 , normalerweise funktionieren alle OPUS immer, es muss nichts damit gemacht werden.

Nachfolgend finden Sie Temperaturmessungen nach 10 Minuten Gebrauch.


Es ist klar, dass wir verschiedene Geräte getestet haben. Dies ist ein Beispiel für ein iPhone, und auf diesem verwendet die OK-Anwendung den Akku am wenigsten, da die Temperatur des Geräts am geringsten ist.

Das zweite, was Sie aktivieren können, wenn Sie WebRTC verwenden, ist das automatische Ausschalten des Videos, wenn die Verbindung sehr schlecht ist .


Wenn Sie weniger als 40 Kbit / s haben, wird das Video ausgeschaltet. Sie müssen nur das Kontrollkästchen aktivieren, wenn Sie die Verbindung herstellen. Der Schwellenwert kann über die Schnittstelle konfiguriert werden. Sie können auch die minimale und maximale Startstrom-Bitrate einstellen.


Dies ist eine sehr nützliche Sache. Wenn Sie beim Herstellen einer Verbindung im Voraus wissen, welche Bitrate Sie erwarten, können Sie diese weiterleiten, der Anruf beginnt von dort und Sie müssen die Bitrate nicht anpassen. Wenn Sie wissen, dass Ihr Kanal häufig Paketverluste oder Bandbreitenverluste aufweist, kann der Maximalwert ebenfalls begrenzt werden.

WhatsApp funktioniert mit sehr seifigen Videos, jedoch mit kleinen Verzögerungen, da die Bitrate von oben aggressiv komprimiert wird.

Wir haben Statistiken mit MaxMind gesammelt und zugeordnet.


Dies ist eine ungefähre Startqualität, die wir für Anrufe in verschiedenen Regionen Russlands verwenden.

Signalisierung


Sie müssen diesen Teil höchstwahrscheinlich schreiben, wenn Sie Anrufe tätigen möchten. Es gibt alle möglichen Fallstricke. Erinnern Sie sich, wie es aussieht.


Es gibt eine Anwendung mit Signalisierung, die eine Verbindung zu SDP herstellt und mit SDP austauscht. Das folgende SDP ist die Schnittstelle zu WebRTC.

So sieht eine einfache Signalisierung aus:


Alice ruft Bob an. Die Verbindung erfolgt beispielsweise über eine Web-Socket-Verbindung. Bob erhält einen Push auf seinem Handy oder Browser oder stellt in einer offenen Verbindung eine Verbindung über eine Web-Buchse her und danach klingelt das Telefon in seiner Tasche. Bob nimmt den Hörer ab, Alice sendet ihm seine Codecs und andere von ihr unterstützte WebRTC-Funktionen. Bob antwortet ihr genauso und danach tauschen sie die Kandidaten aus, die sie gesehen haben. Hurra, ruf an!

Es sieht alles ziemlich lang aus. Erstens klingelt Bobs Telefon nicht in seiner Tasche, bis Sie eine Web-Socket-Verbindung hergestellt haben, bis der Push erfolgt und alles andere. Alice wird die ganze Zeit warten und überlegen, wo Bob ist, warum er nicht zum Telefon greift. Nach der Bestätigung dauert alles Sekunden, und selbst bei guten Verbindungen können es 3-5 Sekunden sein, bei schlechten Verbindungen alle 10.

Wir müssen etwas dagegen tun! Sie werden mir sagen, dass alles sehr einfach gemacht werden kann.



Wenn Sie bereits eine offene Verbindung für Ihre Anwendung haben, können Sie sofort einen Push senden, um eine Verbindung herzustellen, eine Verbindung zum gewünschten Signalisierungsserver herstellen und sofort Anrufe tätigen.

Dann noch eine Optimierung. Selbst wenn das Telefon immer noch in Ihrer Tasche klingelt und Sie das Telefon noch nicht abgenommen haben, können Sie Informationen über die unterstützten Codecs und externen IP-Adressen austauschen, leere Videopakete senden und im Allgemeinen wird alles aufgewärmt. Sobald Sie den Hörer abheben, wird alles großartig.

Wir haben es getan und es schien, dass alles cool war. Aber nein.


Das erste Problem ist, dass Benutzer den Anruf häufig abbrechen. Sie klicken auf "Anrufen" und brechen sofort ab. Dementsprechend geht der Push zum Anruf und der Benutzer verschwindet (er hat das Internet oder etwas anderes verloren). Währenddessen klingelt jemandes Telefon, er nimmt den Hörer ab und wird dort nicht erwartet. Daher funktioniert unsere primitive Optimierung, um so schnell wie möglich mit dem Aufrufen zu beginnen, nicht wirklich.


Mit einer schnellen Anrufannullierung gibt es eine zweite schädliche Sache. Wenn Sie die ID Ihrer Konversation auf dem Server generieren, müssen Sie auf eine Antwort warten. Das heißt, Sie erstellen einen Anruf, erhalten eine ID und können erst danach tun, was Sie wollen: Pakete senden, austauschen, einschließlich des Anrufs abbrechen. Dies ist eine sehr schlechte Geschichte, da sich herausstellt, dass Sie bis zum Eintreffen der Antwort nichts vom Kunden stornieren können. Daher ist es am besten, auf dem Client eine ID wie eine GUID zu generieren und zu sagen, dass Sie den Anruf gestartet haben. Die Leute machen das oft: Sie haben angerufen, abgesagt und sofort wieder angerufen. Um dies zu verhindern, erstellen Sie eine GUID und senden Sie sie ab.


Es scheint nichts zu sein, aber es gibt ein anderes Problem. Wenn Bob zwei Telefone hat oder woanders der Browser geöffnet bleibt, funktioniert unser gesamtes magisches Schema, um Pakete auszutauschen und eine Verbindung herzustellen, nicht, wenn er plötzlich von einem anderen Gerät aus antwortet.

Was tun? Kehren wir zu unserem einfachen einfachen langsamen Signalisierungsschema zurück und optimieren es. Senden Sie den Push etwas früher. Der Benutzer wird schneller eine Verbindung herstellen, dies spart jedoch einige Cent.


Was tun mit dem längsten Teil, nachdem er den Hörer abgenommen und den Austausch gestartet hat?


Sie können Folgendes tun. Es ist klar, dass Alice bereits alle ihre Codecs kennt und sie an beide Telefone von Bob senden kann. Sie kann alle ihre IP-Adressen auflösen und sie auch an die Signalisierung senden, wodurch sie in ihrer Warteschlange bleiben, aber nicht an einen der Clients gesendet werden, damit diese vorzeitig eine Verbindung mit ihr herstellen.

Was kann Bob tun? offer, , , , , , . , codec negotiation, signaling , , . Candidates signaling.

, signaling . , , .

. Google Duo WhatsApp.


, - . , signaling, , , , , , . .

?


: , . , , — signaling , , - , , , .


, , , . . , , , , . , .

, 24/7, -, .




web-socket - load balancer, signaling- -, . Zookeeper Leader Election, signaling, conversation. conversation, .

, NewSQL Cassandra . , . , signaling, , signaling, - , Leader Election Zookeeper, , , .

:

  • - , , IP signaling
  • Signaling , .
  • , , , , .
  • .

, .

Cassandra, ( ).

, :

  • iceServers ;
  • Session Description Protocol;
  • ;
  • signaling WebRTC , IP ;
  • !



:

  • delay ;
  • ;
  • .

Wow!


Security. Man in the middle attack for WebRTC


man in the middle attack for WebRTC. , WebRTC , RTP, 1996 , SDP 1998 SIP.


— RFC RTP, RTP WebRTC.

RFC — audio level, , audio level , . , SDP, , . congestion, -.

WebRTC . 2011 , 2013 Firefox, iOS/Android, 2014 Opera. , - , .


signaling, , DTLS Handshake . , signaling, «» , , , .


, , , HTTPS, WSS .. — ZRTP, , , Telegram.

Telegram , , . , , , , p2p .

Wie funktioniert es


— . , , . . K, , , .

, , K 1 K 2 . . . K 1 K 2 , . K 1 K 2 : , — , — , . , , - , , .

Ergebnisse


  • «» NAT type symmetric NAT.
  • , : 2 relay, , CDN; .
  • , .
  • signaling.



, RTMFP, , WebRTC, , . ! 4 .



, :


, .



HighLoad++ 4-.

, . , 19 (10 9 -) , - . , , .

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


All Articles