DEV Community

Cover image for Share files securely peer to peer with WEBRTC
EneasLari
EneasLari

Posted on

Share files securely peer to peer with WEBRTC

Hello fellow developers, Have you ever wonder if you can share file without a server directly to another peer and realtime? Yes you can and here Ξ™ will show you how to do it.

All code from this tutorial as a complete package is available in GitHub in this repository

The server
Oh ok this is awkward, I just said before "without server" but you need a server just for signaling. How the other peer will find your computer among billion of devices in the internet?

Initialize a new node.js project:
npm init

Install express:
npm install --save express

Install socket.io for signaling:
npm install --save socket.io

Install ejs for server side rendering:
npm install --save ejs

Server code: server.js
This is the simplest server for signaling in order to connect max two peers and one view:

Code explanation

  • At line 12 we use express and ejs to render a simple html page that will help us to make the UI for the file sharing.

  • At line 16 a http server is created and is set to listen to port 3000 or the port defined by a PORT environment variable at line 18

  • At line 20 a new instance of socket.io is initialized and we pass http server as a parameter.

  • At line 22 we listen at the connection event where we have defined all our other events that occur after connection.

  • function log() is a function that emits to the client who sent the message a log event and some message that are defined in the arguments as an array

Lets talk about sockets events that are defined inside our server code.

  • create or join when the server receives this event from the client initially at line 44 it gets the number of clients in room.
    and stores it in var clientsInRoom, if this variable is null then we define the numClients as zero otherwise we set it as the clientsInRoom. At line 49 if the clients who sends the message is the first then we emit the created event to the client otherwise at line 54 if is the second who sends this message we send join to the first client, we join the second client and a joined event is sent to the second client that just joined the room.
    At the end the two clients will receive ready event.
    If anyone else except these two clients send other create or join event he will receive a full event.

  • ipaddr event is for signaling webRTC

For the client your will need a config.js file which contains a json object for STUN/TURN server. I will not explain in details what is this for in this article but it is necessary to help two clients to exchange their public IP Adresses.
The gist above is not correct for security reasons but you can create your own config object at xirsys

Client code for establishing a peer connection:

And the html page:

If you run the server as it is with
node server.js

and visit

http://localhost:3000/

you will see in the debug window in browser:

Image description

If you open a second window and add the same room name you will see through console that an peer connection is established

Image description

After connection:

Image description

Datachannel on peer connection
Now we are ready to create the datachannel for file trasfer
And then send the file to the other peer when the user clicks the send button.

The updated html:

and finally the updated javascript file:

Complete working project:
GitHub repo: link

Any comments or corrections are welcome and appreciated!

Thank you for reading!

Top comments (2)

Collapse
 
bradiskill profile image
Bradiskill

Hi I proceded to run this and found that when I transfered the files, it turned everything into a txt file. For example I tried to transfer a png but it became an encrypted .txt file. Maybe I know why this is happening and how I can fix this. ASAP by today if possible. Thank you

Collapse
 
eneaslari profile image
EneasLari • Edited

Hello, for a quick solution to this problem just change the line 160 with a hardcoded name, for the output file for example: "downloadFile(blob, "image.png");"