WebRTC sert à faire communiquer en temps
réel (avec audio et vidéo) deux navigateurs
Web. Il est déjà largement déployé, ce RFC arrive bien après la
bataille, et décrit les généralités sur WebRTC. Ce protocole est
complexe et offre beaucoup de choix au concepteur
d'applications.
En fait, WebRTC n'est pas vraiment un
protocole. Deux applications utilisant WebRTC peuvent parfaitement
être dans l'incapacité de communiquer. WebRTC est plutôt un cadre
(framework) décrivant des composants, parmi
lesquels le concepteur d'applications choisira. Vu cette
complexité, ce est un point de départ
nécessaire, pour comprendre l'articulation des différents
composants. D'ailleurs, il y a un abus de langage courant : WebRTC
désigne normalement uniquement l'APIJavaScript
normalisée par le
W3C. La communication sur le réseau se nomme rtcweb, et
c'est le nom de l'ex-groupe de travail à
l'IETF. Mais tout le monde fait cet abus de langage et moi
aussi, j'utiliserai WebRTC pour désigner l'ensemble du
système.
L'auteur du RFC est un « vieux de la vieille » et a vu
passer beaucoup de protocoles. Il est donc logique qu'il commence
par quelques rappels historiques en section 1. L'idée de faire
passer de l'audio et de la
vidéo sur l'Internet
est aussi ancienne que l'Internet lui-même, malgré les prédictions
pessimistes des telcos, qui avaient toujours prétendu que cela ne
marcherait jamais. (La variante d'aujourd'hui est « si on ne nous
laisse pas violer la neutralité du
réseau, la vidéo ne marchera jamais ».)
Mais c'est vrai que les débuts ont été laborieux, la capacité du réseau étant très
insuffisante, et les processeurs trop lents. Ça s'est
amélioré par la suite. Mais si le matériel a progressé, les
protocoles continuaient à manquer : il existe bien sûr des
protocoles standards pour traiter certains aspects de la
communication (comme SIP - - pour
la signalisation) mais, pour une
communication complète, il faut un jeu de
protocoles couvrant tous les aspects, de la
signalisation à l'encodage du flux vidéo,
en passant par les identificateurs à utiliser (comme les adresses
de courrier électronique), et qu'on puisse
compter sur ce jeu, de même qu'on peut compter sur la
disponibilité de clients et serveurs HTTP, par exemple. Comme le note
l'auteur, « la Solution Universelle s'est avérée difficile à
développer ». (Cela a d'ailleurs laissé un boulevard à des
entreprises privées, proposant un produit très fermé et
complètement intégré comme le Skype de
Microsoft.)
Depuis quelques années, la disponibilité très répandue de
navigateurs Web ayant
des possibilités très avancées a changé la donne. Plus besoin
d'installer tel ou tel
plugin, telle ou telle
application, désormais, les possibilités qu'offre HTML5 sont largement répandues, et accessibles en
JavaScript via une API standard. Un
groupe de
travail du W3C développe de nouvelles possibilités et
WebRTC peut donc être vu comme un effort commun du W3C et de
l'IETF. C'est sur ces nouvelles possibilités du
navigateur que se fonde WebRTC (son cahier
des charges figure dans le ).
Notre RFC note que WebRTC change pas mal l'architecture des
techniques de communication temps-réel et multimédia. Autant les
solutions fondées sur SIP comptaient sur des éléments
intermédiaires dans le réseau pour travailler (par exemple des
ALG), autant WebRTC est nettement plus
« bout en bout », et utilise la cryptographie pour faire
respecter ce principe, bien menacé par les FAI.
Question histoire, WebRTC a lui-même eu une histoire
compliquée. La première réunion du groupe à
l'IETF a eu lieu en
2011, pour une fin prévue en 2012. En fait, il y a eu des
retards, et même une longue période d'arrêt du travail. Ce RFC de
survol de WebRTC,
par exemple, a vu sa première version publiée il y a huit ans. Le premier
RFC du projet n'a été
publié qu'en 2015. Globalement, ce fut l'un
des plus gros efforts de l'IETF, mais pas le plus efficace en
terme de rapidité. Le groupe de travail rtcweb a finalement été clos en
août 2019, le travail étant terminé.
La section 2 de notre RFC résume les principes de WebRTC :
permettre une communication audio, vidéo et données la plus
directe possible entre les deux participants. Ce est la description générale, les protocoles effectifs
figurent dans d'autres RFC comme le pour le protocole de création du canal de données
ou le pour la
communication via le canal de données. Techniquement, WebRTC a
deux grandes parties :
La spécification du protocole, faite à
l'IETF, dans les et
.L'APIJavaScript
permettant le développement des clients tournant dans les
navigateurs Web, API normalisée par le W3C dans « WebRTC 1.0:
Real-time Communication Between Browsers » et
« Media Capture and
Streams ».
La section 2 décrit également le vocabulaire, si vous voulez
réviser des concepts comme la notion de protocole ou de
signalisation.
La section 3 de notre RFC présente l'architecture
générale. Chaque navigateur WebRTC se connecte à un serveur Web où
il récupère automatiquement un code
JavaScript qui appelle les fonctions
WebRTC, qui permettent d'accéder au canal de données, ouvert avec
l'autre navigateur, et aux services multimédia de son ordinateur
local (le micro, la caméra, etc). On y voit notamment (figure 2)
que les données (la voix, la vidéo, etc) passent directement
(enfin, presque, voir plus loin) entre les deux navigateurs, alors
que la signalisation se fait entre les deux serveurs Web. On note,
et c'est très important, que WebRTC ne gère que le canal de
données, pas celui de signalisation, qui peut utiliser SIP (), XMPP () ou même un protocole privé. C'est entre autres
pour cette raison que deux services WebRTC différents ne peuvent
pas forcément interopérer. Voici un schéma de WebRTC lorsque les
deux parties se connectent au même site Web (la signalisation est
alors faite à l'intérieur de ce site) :
Et ici une image d'une fédération, où les deux parties qui communiquent utilisent
des services différents, mais qui se sont mis d'accord sur un
protocole de signalisation :
Le canal de données nécessite déjà beaucoup de spécifications,
notamment le transport et
l'encodage du contenu. Il est spécifié dans le .
Le transport, justement (section 4 du RFC). Il faut envoyer les
données à l'autre navigateur, et assurer la retransmission des
données perdues, le contrôle de congestion,
etc. Tout cela est décrit dans le . Ce RFC spécifie,
pour transporter les données multimédia, l'utilisation de
SRTP sur DTLS,
lui-même sur UDP (cf. ). Des systèmes de
relais comme TURN () peuvent être nécessaires si les deux malheureux
navigateurs Web soint coincés derrière des middleboxes méchantes,
NAT ou
pare-feu par exemple.
Ce n'est pas tout d'avoir un protocole de transport. Il faut
aussi découper les données d'une manière compréhensible par
l'autre bout (framing, section 5 de notre
RFC). WebRTC utilise RTP (, et voir aussi le ) et SRTP ( et ). Le détaille leur utilisation. La sécurité est, elle,
couverte dans les et . L'établissement du canal de données est normalisé
dans le
et le canal de données lui-même dans le .
On le sait, les formats d'audio et de vidéo sont un problème
compliqué, le domaine est pourri de brevets
souvent futiles, et la variété des formats rend difficile
l'interopérabilité. Notre RFC impose au minimum l'acceptation des
codecs décrits dans le pour l'audio (Opus est
obligatoire) et pour
la vidéo (H.264 et
VP8, après une longue lutte). D'autres codecs pourront s'y ajouter par la suite.
La section 7 mentionne la gestion des connexions, pour laquelle
la solution officielle est le JSEP (JavaScript Session
Establishment Protocol, ).
La section 9 du RFC décrit les fonctions locales (l'accès par
le navigateur aux services de la machine qui l'héberge). Le RFC
rappelle que ces fonctions doivent inclure des choses comme la
suppression d'écho, la protection de la vie
privée (demander l'autorisation avant d'accéder à la caméra…) Le
fournit des détails. Ici, un
exemple d'une demande d'autorisation par
Firefox :
Parmi les logiciels qui permettent de faire du WebRTC, on peut
citer Jitsi, qui est derrière
le service Framatalk, mais
qui est également accessible via d'autres services comme
.
Regarder du trafic WebRTC avec un logiciel comme
Wireshark est frustrant, car tout est
chiffré. Pour Jitsi, on
voit beaucoup de STUN, pour contourner les
problèmes posés par le NAT, puis du
DTLS évidemment impossible à décrypter.
Il y a de nombreux autres logiciels avec WebRTC. C'est le cas
par exemple de PeerTube mais attention,
seul l'échange de vidéo entre pairs qui regardent au même moment
utilise WebRTC (plus exactement WebTorrent,
qui utilise WebRTC). La récupération de la vidéo depuis le serveur
se fait en classique HTTPS.
Si vous voulez voir une session WebRTC, le mieux est d'utiliser
un service comme , qui journalise tout, et d'activer la console de
Firefox. Vous voyez alors :
Console (Webdeveloper tools) Firefox
9.569: Initializing; server= undefined.
Puis l'établissement des canaux nécessaires :
37.252: Opening signaling channel.
39.348: Joined the room.
39.586: Retrieved ICE server information.
39.927: Signaling channel opened.
39.930: Registering signaling channel.
39.932: Signaling channel registered.
Là, Firefox vous demande l'autorisation d'utiliser micro et
caméra, que vous acceptez :
44.452: Got access to local media with mediaConstraints:
'{"audio":true,"video":true}'
44.453: User has granted access to local media.
Le navigateur peut alors utiliser ICE () pour
trouver le bon moyen de communiquer avec le pair (dans mon test,
les deux pairs étaient sur le même réseau local, et s'en
aperçoivent, ce qui permet une communication directe par la
suite) :
44.579: Creating RTCPeerConnnection with:
config: '{"rtcpMuxPolicy":"require","bundlePolicy":"max-bundle","iceServers":[{"urls":["stun:74.125.140.127:19302","stun:[2a00:1450:400c:c08::7f]:19302"]},{"urls":["turn:74.125.140.127:19305?transport=udp","turn:[2a00:1450:400c:c08::7f]:19305?transport=udp","turn:74.125.140.127:19305?transport=tcp","turn:[2a00:1450:400c:c08::7f]:19305?transport=tcp"],"username":"CP/Bl+UXXXXXXX","credential":"XXXXXXXXXXX=","maxRateKbps":"8000"}],"certificates":[{}]}';
constraints: '{"optional":[]}'.
44.775: Created PeerConnectionClient
On peut alors négocier les codecs à
utiliser (ici VP9) :
44.979: Set remote session description success.
44.980: Waiting for remote video.
44.993: No preference on audio receive codec.
44.993: Prefer video receive codec: VP9
Et, ici, on voit passer le descripteur de session (section 7 de
notre RFC), au format
SDP ( et
, et notez
la blague entre SDP et le film 300) :
44.997: C->WSS: {"sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-60.5.1 6947646294855805442 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 23:80:53:8A:DD:D7:BF:77:B5:C7:4E:0F:F4:6D:F2:FB:B8:EE:59:D1:91:6A:F5:21:11:22:C0:E3:E0:ED:54:39\r\na=group:BUNDLE 0 1\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 126\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=fmtp:111 maxplaybackrate=48000;stereo=1;useinbandfec=1\r\na=fmtp:126 0-15\r\na=ice-pwd:bb7169d301496c0119c5ea3a69940a55\r\na=ice-ufrag:3d465335\r\na=mid:0\r\na=msid:{d926a161-3011-48af-9236-06e15377dfea} {a2597b07-7e80-47fe-8542-761dd93efb94}\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtpmap:126 telephone-event/8000/1\r\na=setup:active\r\na=ssrc:2096893919 cname:{e60fd6dc-6c2d-4132-bb6a-1178e1611d16}\r\nm=video 9 UDP/TLS/RTP/SAVPF 98\r\nc=IN IP4 0.0.0.0\r\na=recvonly\r\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=fmtp:98 max-fs=12288;max-fr=60\r\na=ice-pwd:bb7169d301496c0119c5ea3a69940a55\r\na=ice-ufrag:3d465335\r\na=mid:1\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-mux\r\na=rtpmap:98 VP9/90000\r\na=setup:active\r\na=ssrc:4025254123 cname:{e60fd6dc-6c2d-4132-bb6a-1178e1611d16}\r\n","type":"answer"}
Et c'est bon, tout marche :
45.924: Call setup time: 1399ms.
Du fait de son caractère pair-à-pair (les données sont
échangées, autant que le NAT le permet,
directement entre les navigateurs), WebRTC soulève des questions
de vie privée. Votre correspondant va voir
votre adresse IP. Le point est discuté
plus longuement dans le . (PeerTube met en bas un
mot d'avertissement à ce sujet.)
WebRTC est présent depuis pas mal d'années dans tous les
navigateurs graphiques comme Firefox, Chrome ou
Edge. Côté
bibliothèques, il existe de nombreuses
mises en œuvre de WebRTC comme OpenWebRTC (abandonné depuis) ou
comme l'implémentation de
référence. Il y a également du WebRTC dans des serveurs
comme Asterisk,
WebEx ou MeetEcho
(ce dernier étant utilisé par l'IETF pour ses réunions à
distance). Mais rappelez-vous que WebRTC n'est pas un ensemble
cohérent permettant l'interopérabilité. Vous pouvez avoir deux
services WebRTC qui n'arrivent pas à interagir, et ce n'est pas
une bogue, c'est un choix de conception.
Et, pour finir, quelques lectures et activités supplémentaires :
Pour tester votre environnement (micro, caméra, etc) et
votre réseau (beaucoup de réseaux sont truffés de
middleboxes
hostiles), un bon site de test, , c'est vraiment le
premier endroit où aller si vous avez des soucis techniques avec
un service WebRTC,Vous pouvez voir les statistiques d'activité WebRTC dans
votre navigateur, en pour
Chrome, pour
Opera, et pour Firefox,Un bon
tutoriel sur WebRTC, très détaillé, écrit plutôt du point
de vue du programmeur JavaScript écrivant un client,Un bon
résumé de WebRTC, plutôt du point de vue de « comment ça marche »,Le site « officiel » du
projet,Le groupe
de travail au W3C.L'annonce
officielle de la publication des normes.