{"id":141,"date":"2016-11-02T02:10:56","date_gmt":"2016-11-02T02:10:56","guid":{"rendered":"https:\/\/testmozilla.wpengine.com\/webrtc\/?p=141"},"modified":"2016-11-26T05:40:26","modified_gmt":"2016-11-26T05:40:26","slug":"signaling-with-rtcsimpleconnection","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/","title":{"rendered":"Fiddle of the week: Easy-peasy WebRTC Signaling"},"content":{"rendered":"<p>If you think WebRTC signaling is too complicated, then this blog is for you (unless you dislike newfangled JavaScript).<\/p>\n<p>I often hear this complaint: &#8220;Why isn&#8217;t WebRTC as simple as, say, Web Sockets?&#8221;, specifically that &#8220;negotiation is hard&#8221;. While it&#8217;s inherently more complicated to connect to another client than a server, I think this question has some merit with regard to the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/RTCPeerConnection\"><code>RTCPeerConnection<\/code><\/a> API. Let&#8217;s see if we can make things simpler.<!--more--><\/p>\n<p>The WebRTC specification has undergone changes lately, exposing even more surface for professionals to fine-tune real-world use. This is great, but it adds complexity. However, to &#8220;advance WebRTC&#8221; also means making it accessible to non-professionals. This blog attempts to do that, using compact ES6 JavaScript, because new things go together.<\/p>\n<h3>The basics<\/h3>\n<p>First, the basics. I learn by seeing the smallest possible working code doing something observable. Here&#8217;s the &#8220;Hello World&#8221; of WebRTC: One peer connection sending video to another on the same page (click &#8220;Result&#8221; to run it):<\/p>\n<iframe src=\"https:\/\/jsfiddle.net\/jib1\/cwxv3jd2\/embedded\/js,result,html\/\" width=\"100%\" height=\"375px\" frameborder=\"0\"><\/iframe>\n<p>If you&#8217;re familiar with WebRTC, this may be less code than you&#8217;re used to. On the other hand, if you&#8217;re new, your reaction to everything but the first three lines should be: &#8220;What is all this?&#8221; The answer is: <em>signaling<\/em>, which WebRTC has outsourced to you (unless you reacted to the <a href=\"http:\/\/www.html5rocks.com\/en\/tutorials\/es6\/promises\/\">promises<\/a> and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Functions\/Arrow_functions\">arrow functions<\/a>, in which case, come back here after).<\/p>\n<p>This isn&#8217;t even a useful example, because we&#8217;ve short-circuited the signaling to the same page. Enter Web Sockets, except this blog has no server, so we&#8217;re going to cheat and simulate Web Sockets with localStorage. First <a href=\"..\/signaling-with-rtcsimpleconnection\/\">open this blog in a new window<\/a> so you can see them both, then click &#8220;Result&#8221; in both windows to run the following code, <em>before <\/em>finally clicking the &#8220;Connect&#8221; button in one of them (it won&#8217;t work unless they&#8217;re both ready):<\/p>\n<iframe src=\"https:\/\/jsfiddle.net\/jib1\/75cboh1q\/embedded\/js,result,html\/\" width=\"100%\" height=\"425px\" frameborder=\"0\"><\/iframe>\n<p>We are now a bit closer to what real code looks like (I&#8217;ve only left out ICE servers). We&#8217;re sending video to someplace else. But now there&#8217;s even more signaling, and we had to invent a protocol (I chose <code>{ice}<\/code> and <code>{sdp}<\/code>).<\/p>\n<p>Surprisingly, if we want to add or remove tracks mid-call, this signaling is needed even after a connection has been established, even though peer connections have data channels that could do this!<\/p>\n<p>When <a href=\"https:\/\/github.com\/w3c\/webrtc-pc\/issues\/735\">asked<\/a> why WebRTC doesn&#8217;t automate this, the answer (which has merit) from the working group was that it didn&#8217;t meet the &#8220;minimal API&#8221; test, since it could easily be polyfilled, plus they didn&#8217;t want to specify a protocol.<\/p>\n<p>So lets polyfill it!<\/p>\n<h3>The RTCSimpleConnection polyfill<\/h3>\n<p>I call it <a href=\"https:\/\/rawgit.com\/jan-ivar\/simpleconnect\/master\/simpleconnect.js\"><code>RTCSimpleConnection<\/code><\/a>. Our two examples above now become:<\/p>\n<iframe src=\"https:\/\/jsfiddle.net\/jib1\/q2d09hag\/embedded\/js,result,html\/\" width=\"100%\" height=\"250px\" frameborder=\"0\"><\/iframe>\n<p>and cross-tab:<br \/>\n<iframe src=\"https:\/\/jsfiddle.net\/jib1\/4sz20bw2\/embedded\/js,result,html\/\" width=\"100%\" height=\"225px\" frameborder=\"0\"><\/iframe><\/p>\n<p>As you can see, I&#8217;ve moved all signaling into <code>RTCSimpleConnection<\/code>, and we just pass in our socket to its constructor. So simple, I had to shrink the video to fit in the smaller view!<\/p>\n<p>The best part is we haven&#8217;t even explored the real benefit yet. <code>RTCSimpleConnection<\/code> comes with two built-in data channels for chat and signaling (because why not?)<\/p>\n<p>To show the full power of this, here&#8217;s a final cross-tab chat demo that connects <em>before<\/em> video is added, and automatically renegotiates over data channels. After connecting, you can chat instantly back and forth. Either side can hit the &#8220;Add Camera&#8221; button to add their video mid-call (works both ways):<\/p>\n<iframe src=\"https:\/\/jsfiddle.net\/jib1\/t3ruLvny\/embedded\/js,result,html\/\" width=\"100%\" height=\"450px\" frameborder=\"0\"><\/iframe>\n<p>I hope you found this experiment useful, and that you got the demos working side-by-side for full effect. They all use <a href=\"https:\/\/github.com\/webrtc\/adapter\">adapter.js<\/a> and should work in both Firefox and Chrome. However, it won&#8217;t work cross-browser, due to my <a href=\"https:\/\/rawgit.com\/jan-ivar\/localSocket\/master\/localSocket.js\">localSocket<\/a> hack.<\/p>\n<p>You can find the <code>RTCSimpleConnection<\/code> polyfill <a href=\"https:\/\/rawgit.com\/jan-ivar\/simpleconnect\/master\/simpleconnect.js\">here<\/a>. I wrote it with this blog in mind, so I haven&#8217;t fully field-tested it. I&#8217;m sure there are improvements I could make. Hopefully, I&#8217;ve given you a springboard to using data channels for signaling. See you on the web!<\/p>\n","protected":false},"excerpt":{"rendered":"If you think WebRTC signaling is too complicated, then this blog is for you (unless you dislike newfangled JavaScript). I often hear this complaint: &#8220;Why isn&#8217;t WebRTC as simple as, say, Web Sockets?&#8221;, specifically that &#8220;negotiation is hard&#8221;. While it&#8217;s inherently more complicated to connect to another client than a server, I think this question [&hellip;]","protected":false},"author":1399,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[294644,1],"tags":[294871,295893,4870,294644,128,298732,299124,20251],"coauthors":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC\" \/>\n<meta property=\"og:description\" content=\"If you think WebRTC signaling is too complicated, then this blog is for you (unless you dislike newfangled JavaScript). I often hear this complaint: &#8220;Why isn&#8217;t WebRTC as simple as, say, Web Sockets?&#8221;, specifically that &#8220;negotiation is hard&#8221;. While it&#8217;s inherently more complicated to connect to another client than a server, I think this question [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/\" \/>\n<meta property=\"og:site_name\" content=\"Advancing WebRTC\" \/>\n<meta property=\"article:published_time\" content=\"2016-11-02T02:10:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-11-26T05:40:26+00:00\" \/>\n<meta name=\"author\" content=\"Jan-Ivar Bruaroey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan-Ivar Bruaroey\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/\",\"name\":\"Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\"},\"datePublished\":\"2016-11-02T02:10:56+00:00\",\"dateModified\":\"2016-11-26T05:40:26+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/webrtc\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fiddle of the week: Easy-peasy WebRTC Signaling\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/\",\"name\":\"Advancing WebRTC\",\"description\":\"Committed to moving Firefox and WebRTC forward\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\",\"name\":\"Jan-Ivar Bruaroey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"caption\":\"Jan-Ivar Bruaroey\"},\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/","og_locale":"en_US","og_type":"article","og_title":"Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC","og_description":"If you think WebRTC signaling is too complicated, then this blog is for you (unless you dislike newfangled JavaScript). I often hear this complaint: &#8220;Why isn&#8217;t WebRTC as simple as, say, Web Sockets?&#8221;, specifically that &#8220;negotiation is hard&#8221;. While it&#8217;s inherently more complicated to connect to another client than a server, I think this question [&hellip;]","og_url":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/","og_site_name":"Advancing WebRTC","article_published_time":"2016-11-02T02:10:56+00:00","article_modified_time":"2016-11-26T05:40:26+00:00","author":"Jan-Ivar Bruaroey","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jan-Ivar Bruaroey","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/","url":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/","name":"Fiddle of the week: Easy-peasy WebRTC Signaling - Advancing WebRTC","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#website"},"datePublished":"2016-11-02T02:10:56+00:00","dateModified":"2016-11-26T05:40:26+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/webrtc\/signaling-with-rtcsimpleconnection\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/webrtc\/"},{"@type":"ListItem","position":2,"name":"Fiddle of the week: Easy-peasy WebRTC Signaling"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/webrtc\/#website","url":"https:\/\/blog.mozilla.org\/webrtc\/","name":"Advancing WebRTC","description":"Committed to moving Firefox and WebRTC forward","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd","name":"Jan-Ivar Bruaroey","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f","url":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","caption":"Jan-Ivar Bruaroey"},"url":"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/141"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/users\/1399"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/comments?post=141"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/141\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/media?parent=141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/categories?post=141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/tags?post=141"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/coauthors?post=141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}