<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6604313324859652520</atom:id><lastBuildDate>Thu, 19 Feb 2026 13:13:46 +0000</lastBuildDate><category>delicious</category><category>web</category><category>inspiration</category><category>github</category><category>javascript</category><category>elixir</category><category>security</category><category>Developments</category><category>development</category><category>nodejs</category><category>phoenix</category><category>programming</category><category>Design</category><category>webdesign</category><category>angular</category><category>bigdata</category><category>html5</category><category>course</category><category>css3</category><category>webdev</category><category>css</category><category>e-learning</category><category>link</category><category>mobile</category><category>project management</category><category>3D</category><category>code</category><category>compression</category><category>cryptography</category><category>docker</category><category>hadoop</category><category>multimédia</category><category>node</category><category>software</category><category>ssl</category><category>symfony</category><category>test</category><category>tools</category><category>API</category><category>AWS</category><category>MIT</category><category>agile</category><category>analytics</category><category>angularjs</category><category>ansible</category><category>artificial intelligence</category><category>assembly</category><category>cheatsheet</category><category>cluster</category><category>color combinations</category><category>color ideas</category><category>color palette</category><category>color wheel</category><category>colorwheel</category><category>concurrency</category><category>covert channel</category><category>database</category><category>deep learning</category><category>designer</category><category>domain</category><category>email</category><category>erlang</category><category>game development</category><category>google</category><category>html</category><category>library</category><category>machinelearning</category><category>mexico</category><category>multimedia</category><category>nosql</category><category>palette</category><category>password</category><category>patterns</category><category>php</category><category>politics</category><category>react</category><category>responsive</category><category>s3</category><category>software design</category><category>statistics</category><category>testing</category><category>tips</category><category>token</category><category>tutoriel</category><category>url generator</category><category>video</category><category>webgl</category><category>webservice</category><category>windows</category><category>AES</category><category>AI</category><category>Apache Mahout</category><category>Berkeley</category><category>C++ networking engine for game programmers.</category><category>EEA</category><category>FlyersWeb/aria2-ansible</category><category>FlyersWeb/big-list-of-naughty-strings</category><category>FlyersWeb/bitcannon-ansible</category><category>FlyersWeb/dhtbay-ansible</category><category>FlyersWeb/funct</category><category>FlyersWeb/hupothesis</category><category>FlyersWeb/postgresql</category><category>FlyersWeb/vagrant-docker-ansible</category><category>FlyersWeb/xhprof</category><category>Harvard</category><category>JSONP</category><category>Lausanne</category><category>Mahout</category><category>MapReduce</category><category>PRNG</category><category>Programmation</category><category>REST</category><category>RSA</category><category>RakNet is a cross platform</category><category>SPA</category><category>Sécurité</category><category>academy</category><category>accumulo</category><category>algorithm</category><category>animated</category><category>anime</category><category>antipattern</category><category>aria2</category><category>arm</category><category>assembleur</category><category>asynchronous</category><category>aumented reality</category><category>automatic install</category><category>awards</category><category>azawad</category><category>backdoor</category><category>backend</category><category>backup</category><category>best</category><category>bestpractice</category><category>bettercrypto</category><category>bigtable</category><category>bitcoin</category><category>blog</category><category>books</category><category>bootstrap</category><category>bot</category><category>brain</category><category>broadband</category><category>browser</category><category>bubble-sort</category><category>burning man</category><category>c</category><category>c#</category><category>c++</category><category>carousel</category><category>cassandra</category><category>certificate</category><category>changeset</category><category>channel</category><category>child</category><category>ci</category><category>client</category><category>cloud</category><category>cloud computing</category><category>codegeneration</category><category>color</category><category>color scheme</category><category>color theme</category><category>colorset</category><category>comparison</category><category>competency</category><category>compressing</category><category>construction</category><category>continuous integration</category><category>coperlicht</category><category>crawler</category><category>cross domain request</category><category>crossbrowser</category><category>crypto</category><category>datamining</category><category>datascience</category><category>datavisualization</category><category>datetime</category><category>deployment</category><category>designpatterns</category><category>dev</category><category>dht</category><category>directive</category><category>dns</category><category>documentation</category><category>domains</category><category>download</category><category>dragon ball</category><category>dragon ball GT</category><category>dragon ball Z</category><category>dropbox</category><category>ecology</category><category>ecto</category><category>edge</category><category>elasticsearch</category><category>embedded programmation</category><category>encryption</category><category>entity</category><category>environnement</category><category>es6</category><category>español</category><category>evaluation</category><category>evangelion</category><category>exercises</category><category>expat</category><category>express</category><category>expressjs</category><category>file sharing</category><category>flash</category><category>flexbox</category><category>font</category><category>forest</category><category>forex</category><category>formation</category><category>free</category><category>french</category><category>front-end</category><category>fwa</category><category>gadget</category><category>game</category><category>gamedev</category><category>geocoding</category><category>geolocalization</category><category>gpu</category><category>graphql</category><category>h.264</category><category>haskell</category><category>hbase</category><category>health</category><category>https</category><category>hupothesis</category><category>ile-de-france</category><category>immutable</category><category>innovation</category><category>intercom</category><category>interface</category><category>it design</category><category>java</category><category>javascriptes6harmony</category><category>jquery</category><category>khan</category><category>knowledge</category><category>learn</category><category>lectures</category><category>lien</category><category>linux</category><category>lookup</category><category>machine learning</category><category>manager</category><category>mandarin</category><category>manga</category><category>map</category><category>maps</category><category>mariadb</category><category>maryland</category><category>math</category><category>metasploit</category><category>metropolis</category><category>middleware</category><category>ml</category><category>mnist</category><category>modelingtools</category><category>module</category><category>mysql</category><category>nasm</category><category>nature</category><category>nessus</category><category>news</category><category>newsletter</category><category>nexpose</category><category>no</category><category>node.js</category><category>npm</category><category>online</category><category>oop</category><category>open source</category><category>opendata</category><category>opensource</category><category>openvas</category><category>parallax</category><category>pattern</category><category>performance</category><category>phantomjs</category><category>pharmacy</category><category>photography</category><category>phpunit</category><category>planit</category><category>plugin</category><category>police</category><category>practice</category><category>presentation</category><category>process-manager</category><category>product strategy</category><category>production</category><category>productivity</category><category>provision</category><category>publishing</category><category>reading</category><category>redpen</category><category>redux</category><category>research</category><category>retro-gaming</category><category>revision</category><category>riak</category><category>safecolors</category><category>sass</category><category>school</category><category>scrum</category><category>send mail</category><category>seo</category><category>server</category><category>short</category><category>shortener</category><category>shortid</category><category>skills</category><category>slider</category><category>slimer</category><category>smartphone</category><category>sort</category><category>spanish</category><category>spark</category><category>sql.js</category><category>sqlite</category><category>stocks</category><category>storytelling</category><category>swagger</category><category>sysadmin</category><category>sécurité informatique</category><category>tagging</category><category>tdd</category><category>thumbnail</category><category>torrent</category><category>tracking</category><category>tradetools</category><category>trading</category><category>tricks</category><category>tutorial</category><category>typescript</category><category>typography</category><category>uml</category><category>unity3d</category><category>url</category><category>utilities</category><category>uuid</category><category>vagrant</category><category>versioning</category><category>videos</category><category>web assembly</category><category>webcolors</category><category>webdesigner</category><category>webrtc</category><category>website</category><category>websocket</category><category>welcome</category><category>wheel</category><category>whois</category><category>work</category><category>writing</category><category>yourls</category><category>zip</category><category>écologie</category><title>Nassim&#39;s Web Developer blog</title><description>I&#39;m Nassim, a web developer and I&#39;m sharing with you some programming tips and tricks</description><link>https://flyers-web.blogspot.com/</link><managingEditor>noreply@blogger.com (Nassim)</managingEditor><generator>Blogger</generator><openSearch:totalResults>126</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>1</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6604313324859652520.post-213816288002681049</guid><pubDate>Mon, 13 Jan 2020 17:32:00 +0000</pubDate><atom:updated>2020-01-13T09:32:05.849-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">file sharing</category><category domain="http://www.blogger.com/atom/ns#">web</category><category domain="http://www.blogger.com/atom/ns#">webrtc</category><title>Sending file through WebRTC</title><description>&lt;h3&gt;
Introduction&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Back in 2016, I’ve worked on an application called ShareTC that allowed users to &lt;b&gt;share their files through their web browser &lt;/b&gt;using the &lt;a href=&quot;https://webrtc.org/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;WebRTC technology&lt;/a&gt;. The application was working well but the promise was to be able to &lt;b&gt;share files without any server&lt;/b&gt;. The first version used &lt;a href=&quot;https://peerjs.com/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;PeerJS&lt;/a&gt;, a library allowing you to implement &lt;a href=&quot;https://www.html5rocks.com/en/tutorials/webrtc/datachannels/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;WebRTC data channel &lt;/a&gt;for file sharing easily with the drawback needing a server for what is called the &lt;a href=&quot;https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;signaling process&lt;/a&gt;. Thus, I’ve made some improvement to the project to allow user to share their files without even using a signaling server.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
For those who are no interested by the technical implementation you can directly have a look to the &lt;b&gt;&lt;a href=&quot;https://flyersweb.github.io/sharetc&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;demo on GitHub&lt;/a&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Migration&lt;/h3&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Originally, the project was barebone native JavaScript but I decided to upgrade the project to &lt;b&gt;Angular 8&lt;/b&gt;, because exchanging the signaling configuration is a little complex, I needed some framework for easy DOM manipulation.&lt;br /&gt;
&lt;br /&gt;
Because this is a side project, I didn’t want to recreate a component library so I used the &lt;a href=&quot;https://material.angular.io/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;@angular/material &lt;/a&gt;library for the forms and user feedbacks.&lt;br /&gt;
&lt;br /&gt;
I also used &lt;a href=&quot;https://github.com/angular/flex-layout&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;@angular/flex-layout&lt;/a&gt; to easily define the layout, knowing that the application design is really basic as it is not the primary intent of the demonstration.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
How it works&lt;/h3&gt;
&lt;br /&gt;
So, the interesting part now, the application will try to create a data channel between the sender and the receiver, using WebRTC. The protocol needs to know to whom it should send the data, this is named &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;peer discovery&lt;/a&gt;, and it can be done automatically through what is called a &lt;b&gt;&lt;a href=&quot;https://github.com/peers/peerjs-server&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;signaling server&lt;/a&gt;&lt;/b&gt;, a server where you exchange your configuration to begin the communication and this is the component that I wanted to remove. For the manual configuration we use the &lt;a href=&quot;https://en.wikipedia.org/wiki/Session_Description_Protocol&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Session Description Protocol &lt;/a&gt;(or SDP).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEYIJkzVg_JPSQigEbEIT5HgTBC_JnTQg5q82c1f0yKkD9Wct4GokDKg_knv0KwnjzNHpQDT1Hbc9KqflCJATB5WFnCPSVwFO0oKuCIY4fvxha3Wglxu8MNidydD6fK1mtheKNAA_5FMZy/s1600/nat.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;515&quot; data-original-width=&quot;834&quot; height=&quot;394&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEYIJkzVg_JPSQigEbEIT5HgTBC_JnTQg5q82c1f0yKkD9Wct4GokDKg_knv0KwnjzNHpQDT1Hbc9KqflCJATB5WFnCPSVwFO0oKuCIY4fvxha3Wglxu8MNidydD6fK1mtheKNAA_5FMZy/s640/nat.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt; &lt;br /&gt; But because the network is a little complex, in some cases, you’ll need a &lt;a href=&quot;https://en.wikipedia.org/wiki/STUN&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Session Traversal Utilities for NAT &lt;/a&gt;(or &lt;b&gt;STUN&lt;/b&gt;) &lt;b&gt;server&lt;/b&gt;. This is used when you’re exchanging a file from behind a &lt;a href=&quot;https://en.wikipedia.org/wiki/Network_address_translation&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Network Address Translation &lt;/a&gt;(or &lt;b&gt;NAT&lt;/b&gt;) &lt;b&gt;firewall&lt;/b&gt;. There are some public servers available for this like:&lt;br /&gt; -&amp;nbsp;&amp;nbsp; &amp;nbsp;stun.services.mozilla.com&lt;br /&gt; -&amp;nbsp;&amp;nbsp; &amp;nbsp;stun.l.google.com:19302&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGp-woHDPm8ILavrlwPL-mipb8gkV64xjQnoiDTzKF6_WvON6yAYsft3J5pFm5nPpaVr1yITjVChV8UETal165a36vQQQc9NWSk9I4Q5KM7qGQNI9VBel2c14Vk1DwpS0CVWVmRnpSZtWQ/s1600/stun.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;568&quot; data-original-width=&quot;834&quot; height=&quot;434&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGp-woHDPm8ILavrlwPL-mipb8gkV64xjQnoiDTzKF6_WvON6yAYsft3J5pFm5nPpaVr1yITjVChV8UETal165a36vQQQc9NWSk9I4Q5KM7qGQNI9VBel2c14Vk1DwpS0CVWVmRnpSZtWQ/s640/stun.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
In some other cases the communication channel will be blocked by firewalls. In this case you can eventually use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Traversal Using Relays around NAT &lt;/a&gt;(or &lt;b&gt;TURN&lt;/b&gt;) &lt;b&gt;server &lt;/b&gt;that will work as a Data relay between you and the peer. They are expensive and only necessary if you’re behind a blocking firewall so I didn’t integrate a solution for that 😊&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9C9uRQuzdqshPaONBZa4HSUU3gykJHD-sFWHq86FJz-8A8hj-HjtQaqGkGEd4m1FJ0zOOcV6JUpcQdNKA23l-iTzTYo1-cLGF5N22Nq1AAmCw8F693MiFHmXuT2ZFOPH0srqhg4jvjXZt/s1600/turn.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;568&quot; data-original-width=&quot;834&quot; height=&quot;434&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9C9uRQuzdqshPaONBZa4HSUU3gykJHD-sFWHq86FJz-8A8hj-HjtQaqGkGEd4m1FJ0zOOcV6JUpcQdNKA23l-iTzTYo1-cLGF5N22Nq1AAmCw8F693MiFHmXuT2ZFOPH0srqhg4jvjXZt/s640/turn.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
So, what do we do is, we generate the sender configuration SDP, that you will need to share with the receiver. Then he’ll be able to generate his SDP configuration, that you’ll need to import in order to create the communication channel. Then you’ll be able to send the file using &lt;a href=&quot;https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Datagram Transport Layer Security &lt;/a&gt;(or &lt;b&gt;DTLS&lt;/b&gt;) which is a secure communication channel.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
How to make it happen&lt;/h3&gt;
&lt;br /&gt;
Now that you have the WebRTC communication scheme in mind, let’s see some interesting parts of the project. You might want to have &lt;b&gt;the code &lt;/b&gt;open to better understand this part by accessing the project repository &lt;a href=&quot;https://github.com/FlyersWeb/sharetc&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;flyersweb/sharetc&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt; First, I chose to use the great &lt;b&gt;&lt;a href=&quot;https://github.com/feross/simple-peer&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;feross/simple-peer&lt;/a&gt; library&lt;/b&gt; for WebRTC communication channel. To use the library we had to add some polyfills (check polyfills.ts) to the project for the global, process and buffer objects like this: &lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #204a87;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;global&lt;/span&gt; &lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #204a87;&quot;&gt;window&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #204a87;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;process&lt;/span&gt; &lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: black;&quot;&gt;nextTick&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;setImmediate&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;,&lt;/span&gt;
    &lt;span style=&quot;color: black;&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;DEBUG&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;undefined&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;},&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;};&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #204a87;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;global&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;Buffer&lt;/span&gt; &lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #204a87;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;global&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;Buffer&lt;/span&gt; &lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&#39;buffer&#39;&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;Buffer&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
If you’re using typescript you also might have to add the node declarations for native modules by modifying your &lt;em&gt;tsconfig.app.json&lt;/em&gt; file with: &lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;types&quot;&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;[&lt;/span&gt;
  &lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;node&quot;&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;],&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
I’ve also decided to &lt;b&gt;compress SDP configuration &lt;/b&gt;using &lt;a href=&quot;https://github.com/pieroxy/lz-string&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;LZ-based compression &lt;/a&gt;so it is easier to share. This is why the configurations will look more like this:&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; &lt;span style=&quot;color: black;&quot;&gt;N4IgLgngDgpiBcID2AzFMBOIA0IDOAJlAiAG4C8ADADobUB2S5AtkgF4CWANlwIYB0ggCoAJAJIBlAPqSpEgCIAFAIIAlIcoC0Adkr89ARgAEBgEwAWSuYCcZ7dZsAOc6e2Ptpo5SNiAcj8VzL30Qmjp6PHJNWgYwKi8Y&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;l5yPBh6AgwYAGNSROSUDnoAc0woDEKweDwAC15NUwBWADYjJuV4JoaO63gAZgAxeEcm&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;ABRAGF4bXN4W3h5Qf7JxvhzLoNBptGxyYbt0ZGG9tH5eGVtpp63eH7KVZ7lRzGDeHG769M7&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;Rf5O4AhUZ5chFDBIACuUHgfwAqr55AAZUYJcLJZh4DgETSpZi8ehgDhZeAAdQAshIjAAqRLMci8KBQLgE3j4pD0IwNRyOUwtaFKAD08iE8IkfIk4yEiiMAHcYAAjDBgLKaAjM3hZWr0egwLiJLLkPwBILWPTG&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;iNfgGXqOIFZXEEDHMmDwbzGXmS0xmUyNRrmXomPR6UwWhpGXraXq2IyQKBGapIPBgG12h1gJ1&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #0000cf; font-weight: bold;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;xCcbugyUBoNCzmez&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;kJBgwh6xR6Cx&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;NgKNZKDRmBGNX40gwJPpFNO4yupQmJrDXOmYZ&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #0000cf; font-weight: bold;&quot;&gt;02&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;m82WxzszncysxvAYFBcAAeRgwvAIGWLgeDa6gSAVofDtiBqXSmRyQLSmNQmltnZVqbwQIJME0UClBCm9m0TVzsosUwshgbRZRgdx7GaAhZQIT4slMFAAJfYDNDBFB1yKeAGmsD0DHA3ogWYDFnVPGAwAheAWygXg8GfFEUiyMAoHfA9KgaSgOMI3hl00ZgYFo3gSixDg2G7Shw2mAwuQI8IQAAXyAA&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
But by decompressing it you’ll get a valid SDP signal message.&lt;br /&gt; &lt;br /&gt; And finally, in order to send and download the file we use the &lt;a href=&quot;https://www.html5rocks.com/en/tutorials/file/dndfiles/&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;JavaScript File API&lt;/a&gt; so we can send it through the data channel. Thing is, the data will be stored as an &lt;a href=&quot;https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/ArrayBuffer&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;ArrayBuffer&lt;/b&gt;&lt;/a&gt; so we generate a download link through a Blob for the file to be downloaded with the name file.dat as shown in the &lt;a href=&quot;https://github.com/FlyersWeb/sharetc/blob/upgrade/src/app/download/download.component.ts&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;download component&lt;/strong&gt;&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt; To exchange messages through the communication data channel we also need to convert the ArrayBuffer to string by using this function:&lt;br /&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;ab2str&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;buf&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;ArrayBuffer&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #ce5c00; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #204a87;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;fromCharCode&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;apply&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;Uint16Array&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;buf&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;));&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
You can check how it is used in the &lt;a href=&quot;https://github.com/FlyersWeb/sharetc/blob/upgrade/src/app/upload/upload.component.ts&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;upload component&lt;/strong&gt;&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
The demo&lt;/h3&gt;
&lt;br /&gt;
Because you have to exchange the &lt;b&gt;SDP configuration &lt;/b&gt;and create the data channel before sending the file, the application is a little more complex to grasp. So to use the demo application you’ll need to:&lt;br /&gt;&lt;br /&gt; 1. Send your sender configuration&lt;br /&gt; 2. Receiver will enter your configuration and hit connect (it connects to sender)&lt;br /&gt; 3. The receiver will the share his generated configuration with you the sender&lt;br /&gt; 4. Then the sender hit connect to create the data channel&lt;br /&gt; 5. The duplex stream is up and running&lt;br /&gt;&lt;br /&gt; You can access it by accessing &lt;a href=&quot;https://flyersweb.github.io/sharetc&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;https://flyersweb.github.io/sharetc&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Conclusion&lt;/h3&gt;
&lt;br /&gt;
This was a long road to have the application that I wanted. To allow users to share their file securely without any server, but I’m really happy to have achieved it besides the network complexity and thanks to the projects that make using WebRTC each day easier.&lt;br /&gt;
&lt;br /&gt; You can check the project source code on the github repository &lt;a href=&quot;https://github.com/FlyersWeb/sharetc&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;flyersweb/sharetc&lt;/a&gt; and give me a tip so that I can buy me a coffee to work more on this 😊</description><link>https://flyers-web.blogspot.com/2020/01/sending-file-through-webrtc.html</link><author>noreply@blogger.com (Nassim)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEYIJkzVg_JPSQigEbEIT5HgTBC_JnTQg5q82c1f0yKkD9Wct4GokDKg_knv0KwnjzNHpQDT1Hbc9KqflCJATB5WFnCPSVwFO0oKuCIY4fvxha3Wglxu8MNidydD6fK1mtheKNAA_5FMZy/s72-c/nat.png" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>