How to build a file transfer application with node and webRTC

Search for a command to run...

Thanks for publishing this interesting series. Can you publish the complete code for this project?
Yes sure, can you email me at piyushgarg.dev@gmail.com
With WebRTC, you can add real-time communication capabilities to your application that works on top of an open standard.
Hey there, in this article we would be building a one-to-many video-conferencing application. We would be using SFU architecture to implement this. To read more about webRTC architectures, visit Different WebRTC Architectures Note: This article is ...
Twitter is one of the most popular social media platforms in the world, with over 330 million active users as of 2021. If you are interested in building a Twitter-like application, this tutorial will guide you through the process of building a FullSt...

Hey everyone, In this article, we will build our own Tic Tac Toe game using pure Javascript. https://youtu.be/lKe57l8sttw Code <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE...

Hi everyone, In this blog, we will learn how we can create node.js functions locally and deploy them to AWS Lambda using serverless. So, let's get started. Step 1. Create an AWS Account ☁️ In order to deploy functions to AWS Lambda, you should have a...

Hey there, In this article, we are going to learn how you can upload any file to firebase storage. Uploading files to firebase storage is really easy. I would I recommend you to code along with me for better understanding. So, let's get started. Step...

Hey there, Welcome back. In this article, I would be showing you how I made a collaborative IDE with a video call. The main application of this application is that you can create a room and people can join the room. You have the ability to write mark...

Hello there, In this article, we would be building a file transfer application using webRTC and node.js. This app would let users transfer heavy files to each other without the need for a server.
Note, in order to proceed with the tutorial, I would highly recommend you to please read my previous tutorial on webRTC Build a video chat app with webRTC.
Alright, let's begin.
In this very step, we are going to set up a simple signaling server using node and socket.io. I won't be explaining the signaling process as I have already that in Build a video chat app with webRTC article. If you haven't read that, please go and read.
// signaling server
const http = require('http');
const express = require('express');
const { Server: SocketIO } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new SocketIO(server, { cors: true });
const PORT = process.env.PORT || 8000;
app.use(express.static('./public'));
io.on('connection', socket => {
socket.emit('me', socket.id);
socket.on('make:offer', data => {
const { offer, to } = data;
socket.to(to).emit('incomming:offer', { offer, from: socket.id });
});
socket.on('make:answer', data => {
const { answer, to } = data;
socket.to(to).emit('incomming:answer', { answer, from: socket.id });
});
});
server.listen(PORT, () => console.log(`🚀 Server started at PORT${PORT}`));
Very basic, no rocket science. I hope that the above code is clear to you.
Let's start with a basic boiler plate code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3 id="my-id"></h3>
<form id="connect">
<input type="text" id="id" />
<button type="submit">SEND</button>
</form>
<form id="file-transfer">
<input id="file" type="file" />
<button type="submit">SEND</button>
</form>
<script src="/socket.io/socket.io.js"></script>
</body>
</html>
Pretty simple.
Now let's define some global variables.
const form = document.getElementById('file-transfer');
const connectForm = document.getElementById('connect');
const socket = io();
const peer = new RTCPeerConnection();
let dataChannel;
Alright, good going 🚀
Now let's add some event listeners to our form and socket.
socket.on('me', id => document.getElementById('my-id').innerText = id); // to get our own socket id.
form.addEventListener('submit', async (ev) => {
ev.preventDefault();
});
connectForm.addEventListener('submit', async (ev) => {
ev.preventDefault();
});
So, what we would be doing is, when a user submits the connection form, we are going to init the signaling process and connect both the peers.
connectForm.addEventListener('submit', async (ev) => {
ev.preventDefault();
const remoteId = document.getElementById('id').value;
const offer = await peer.createOffer();
await peer.setLocalDescription(new RTCSessionDescription(offer));
// This dataChanel we are going to use to send data
dataChannel = peer.createDataChannel('file-transfer');
socket.emit('make:offer', { offer, to: remoteId });
});
and now, create an event listener for the incoming offer
socket.on('incomming:offer', async data => {
await peer.setRemoteDescription(new RTCSessionDescription(data.offer));
const answer = await peer.createAnswer();
await peer.setLocalDescription(new RTCSessionDescription(answer));
socket.emit('make:answer', { answer, to: data.from })
// Init the remote datachannel as soon as the first peer creates a data channel
peer.addEventListener('datachannel', ev => {
dataChannel = ev.channel
dataChannel.send('Hello Peer');
});
})
and finally, the incoming answer
socket.on('incomming:answer', async data => {
await peer.setRemoteDescription(new RTCSessionDescription(data.answer));
})
form.addEventListener('submit', async (ev) => {
ev.preventDefault();
// Get the file from input field.
const file = document.getElementById('file').files[0];
// convert the file to buffer
const fileBuffer = await file.arrayBuffer();
// finally, send it to the peer data channel
dataChannel.send(fileBuffer);
});
Great, so on the receiver side, listen for this file and download the file to the client.
connectForm.addEventListener('submit', async (ev) => {
ev.preventDefault();
const remoteId = document.getElementById('id').value;
const offer = await peer.createOffer();
await peer.setLocalDescription(new RTCSessionDescription(offer));
// This dataChanel we are going to use to send data
dataChannel = peer.createDataChannel('file-transfer');
socket.emit('make:offer', { offer, to: id });
// Adding a message listener
dataChannel.addEventListener('message', ev => {
if (typeof ev.data == 'object') {
const a = document.createElement('a');
const blob = new Blob([ev.data]);
const obj = URL.createObjectURL(blob);
a.href = obj;
a.download = 'rec.png';
a.click()
}
});
});
And that's it, the file would get downloaded to the client's machine.