In the process of working on You, Me, and Our Computers, I have been developing my underlying server and client code to be released as an open-source tool. This week I released the first version of the shared server and client code and wrote a Medium post explaining the tool. Here’s the text of the Medium post, republished here.
A quick intro to signaling, STUN and TURN, and an open-source signaling server and wrapper for simple-peer.
Back in 2015 I built an open-source tool that depends on PeerJs. A few years later I was giving the tool a revamp and noticed a number of errors coming from PeerJS, which had been deprecated by its original developer around 2014. After some research into alternatives for PeerJS, I found that simple-peer by Feross was well documented, well maintained, and used by a number of projects. But it was missing one important component—a signaling server.
Since then, I’ve been slowly gathering information about signaling, STUN, and TURN servers, and ultimately creating my own open-source signaling server and wrapper for simple-peer. Here’s a compilation of what I’ve learned, the resources I’ve found helpful, and a short introduction to the tool that I’ve built.
First things first. Peer connections, which are part of WebRTC, are direct connections between two computers (called “peers”) and are used to send video, audio, and data directly between the two computers. Peer connections are distinct from connections to a server because they allow for direct exchange of information between peers, rather than going through a server.
While the two peers can communicate directly with each other once they have a peer connection, WebRTC does not give peers a way to find each other to establish a connection—that’s where a signaling server comes in.
A signaling server is a server that allows peers to find each other and to establish a peer connection. It exists outside of WebRTC, but is an essential component to establishing a peer connection.
Simple-peer is a library that creates one-to-one peer connections, but it does not include a signaling server.
The simple-peer library creates peer connections, but does not handle signaling.
I wanted to use simple-peer for my project, but I could not find an open-source signaling server for it. So, I built one with the help of the Codelab on Real time communication with WebRTC. A year later, I taught a class at NYU using peers, and I realized I needed a tool to use for my class examples. This is what inspired me to develop the signaling server I wrote into something useable by others.
The tool I built is made up of two modules: simple-peer-server and simple-peer-wrapper. First, you need to get the server up and running.
// in your terminal — install the module
npm install simple-peer-server
// in your application file — create the server
const SimplePeerServer = require('simple-peer-server');
const http = require('http');
const server = http.createServer();
const spServer = new SimplePeerServer(server);server.listen(8081);
// in your terminal — run it!
node app.js
Then, you need to include the wrapper in your client code.
// in your terminal — install the module
npm install simple-peer-wrapper
// in your client code - create a wrapper and connect to your server
const options = {
serverUrl: 'http://localhost:8081',
};
const spw = new SimplePeerWrapper(options);
spw.connect();
spw.on('data', (data) => {
const partnerData = data.data;
});
// make sure you close the connection before you close the window
window.onbeforeunload = () => {
spw.close();
};
The code above connects to the signaling server, creates a peer connection using simple-peer, and stores the data received from the other peer in a variable. The full documentation and example code is available here (server) and here (wrapper).
Simple-peer-server and simple-peer-wrapper together provide a signaling server and client that establish a connection between two or more peers.
They use Socket.IO to transport the signaling messages, then create the peer connections via simple-peer.
To just get up and running, you can run a signaling server and your client code on your localhost.
If you are launching your application on the public internet, you will likely need STUN and TURN servers as well. STUN and TURN servers are responsible for getting the IP address for the peers. STUN servers can get a public IP address for about 86 percent of connections. If you are just testing locally or creating a class project, STUN servers will likely do the trick. For the other 14 percent, and for applications that need to work reliably on the public internet, a TURN server is needed to get past certain firewalls.
Default STUN servers are provided by simple-peer. (Although they can be overwritten in simple-peer-wrapper.) TURN servers can be expensive to maintain and need to be provided by the application developer (that’s probably you if you’re reading this ;).
To learn more about signaling, STUN, and TURN servers, I recommend this excellent article by Sam Dutton. If you are in need of a TURN server, you may find this article on How to set up and configure your own TURN server using Coturn by Gabriel Turner helpful. You could also check out paid services like Twilio’s Network Traversal Service.
Once you have your TURN servers setup, see the simple-peer-wrapper documentation for how to add them to your peer connections.
Here are the references that I found helpful as I was researching and building this. Please feel free to share other helpful resources in the comments :)