PeerJS simplifies peer-to-peer data, video, and audio calls.
This guide will show you the basic concepts of the PeerJS API.
Add the PeerJS client library to your webpage.
<script src="https://unpkg.com/peerjs@1.5.4/dist/peerjs.min.js"></script>
If you prefer, you can host it yourself: peerjs.min.js, or fork us on Github.
The Peer object is where we create and receive connections.
var peer = new Peer();
PeerJS uses PeerServer for session metadata and candidate signaling. You can also run your own PeerServer if you don't like the cloud.
We're now ready to start making connections!
Every Peer object is assigned a random, unique ID when it's created.
peer.on('open', function(id) { console.log('My peer ID is: ' + id); });
When we want to connect to another peer, we'll need to know their peer id.
You're in charge of communicating the peer IDs between users of your site.
Optionally, you can pass in your own IDs to the
Peer
constructor .
Read the Peer API reference for complete information on its options, methods, events, and error handling.
Start a data connection by calling peer.connect
with the peer
ID of the destination peer. Anytime another peer attempts to connect to
your peer ID, you'll receive a connection
event.
var conn = peer.connect('dest-peer-id');
peer.on('connection', function(conn) { ... });
peer.connect
and the callback of the
connection
event will both provide a
DataConnection
object. This object will allow you to send and
receive data:
conn.on('open', function() { // Receive messages conn.on('data', function(data) { console.log('Received', data); }); // Send messages conn.send('Hello!'); });
Read the DataConnection API reference for complete details on its methods and events.
Call another peer by calling peer.call
with the peer ID of
the destination peer. When a peer calls you, the call
event
is emitted.
Unlike data connections, when receiving a call
event, the
call must be answered or no connection is established.
// Call a peer, providing our mediaStream var call = peer.call('dest-peer-id', mediaStream);
peer.on('call', function(call) { // Answer the call, providing our mediaStream call.answer(mediaStream); });
When calling or answering a call, a MediaStream should be provided. The
MediaStream represents the local video (webcam) or audio stream and can be
obtained with some (browser-specific) version of
navigator.getUserMedia
. When answering a call, the MediaStream is optional and if none is
provided then a one-way call is established. Once the call is established,
its open
property is set to true.
peer.call
and the callback of the call
event
provide a MediaConnection object. The MediaConnection object itself emits
a stream
event whose callback includes the video/audio stream
of the other peer.
call.on('stream', function(stream) { // `stream` is the MediaStream of the remote peer. // Here you'd add it to an HTML video/canvas element. });
Read the MediaConnection API reference for complete details on its methods and events.
PeerJS has the BinaryPack serialization format built-in. This means you can send any JSON type as well as binary Blobs and ArrayBuffers. Simply send arbitrary data and you'll get it out the other side:
conn.send({ strings: 'hi!', numbers: 150, arrays: [1,2,3], evenBinary: new Blob([1,2,3]), andMore: {bool: true} });
A small percentage of users are behind symmetric NATs. When two symmetric NAT users try to connect to each other, NAT traversal is impossible and no connection can be made. A workaround is to proxy through the connection through a TURN server. The PeerServer cloud service provides a free TURN server. This will allow your PeerJS app to work seamlessly for this situation
When creating your Peer object, pass in the ICE servers as the config key of the options hash.
var peer = new Peer({ config: {'iceServers': [ { url: 'stun:stun.l.google.com:19302' }, { url: 'turn:homeo@turn.bistri.com:80', credential: 'homeo' } ]} /* Sample servers, please use appropriate ones */ });
When you try to connect to a peer, PeerServer will hold a connection offer for up to 5 seconds before rejecting it. This is useful if you want to reconnect to a peer as it disconnects and reconnects rapidly between web pages.
You could be behind a symmetric NAT, in which case you'll need to set up a TURN server.
Another possible issue is your network blocking port 443, which the PeerServer cloud runs on. In this you must use your own PeerServer running on an appropriate port instead of the cloud service.
Data sent between the two peers do not touch any other servers, so the connection speed is limited only by the upload and download rates of the two peers. This also means you don't have the additional latency of an intermediary server.
The latency to establish a connection can be split into two components: the brokering of data and the identification of clients. PeerJS has been designed to minimize the time you spend in these two areas. For brokering, data is sent through an XHR streaming request before a WebSocket connection is established, then through WebSockets. For client identification, we provide you the ability to pass in your own peer IDs, thus eliminating the RTT for retrieving an ID from the server.
A peer can connect to other peers and listen for connections.
Other peers can connect to this peer using the provided ID. If no ID
is given, one will be generated by the brokering server. The ID must
start and end with an alphanumeric character (lower or upper case
character or a digit). In the middle of the ID spaces, dashes (-)
and underscores (_) are allowed.It's not recommended that you use this ID to identify peers, as
it's meant to be used for brokering connections only. You're
recommended to set the
metadata
option to
send other identifying information.
API key for the cloud PeerServer. This is not used for servers
other than 0.peerjs.com
.PeerServer cloud runs on port 443. Please ensure it is not
blocked or consider running your own PeerServer instead.
Server host. Defaults to 0.peerjs.com
. Also accepts
'/'
to signify relative hostname.
Server port. Defaults to 443
.
Ping interval in ms. Defaults to 5000
.
The path where your self-hosted PeerServer is running. Defaults
to '/'
.
true
if you're using SSL.Note that our cloud-hosted server and assets may not support
SSL.
Configuration hash passed to RTCPeerConnection. This hash
contains any custom ICE/TURN server configuration. Defaults to
{ 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }],
'sdpSemantics': 'unified-plan' }
Connects to the remote peer specified by id
and returns a
data connection. Be sure to listen on the
error
event in case the
connection fails.
A unique label by which you want to identify this data
connection. If left unspecified, a label will be generated at
random. Can be accessed with
dataConnection.label
.
Metadata associated with the connection, passed in by whoever
initiated the connection. Can be accessed with
dataConnection.metadata
. Can be any serializable type.
Can be binary
(default), binary-utf8
,
json
, or none
. Can be accessed with
dataConnection.serialization
.binary-utf8
will take a performance hit because
of the way UTF8 strings are packed into binary format.
Whether the underlying data channels should be reliable (e.g.
for large file transfers) or not (e.g. for gaming or streaming).
Defaults to false
.Setting reliable to true will use a shim for incompatible
browsers (Chrome 30 and below only) and thus may not offer
full performance.
Calls the remote peer specified by id
and returns a media
connection. Be sure to listen on the
error
event in case the
connection fails.
The caller's media stream
Metadata associated with the connection, passed in by whoever
initiated the connection. Can be accessed with
mediaConnection.metadata
. Can be any serializable type.
Function which runs before create offer to modify sdp offer message.
Set listeners for peer events.
Emitted when a connection to the PeerServer is established. You may
use the peer before this is emitted, but messages to the server will
be queued. id
is the brokering ID of the peer (which
was either provided in the constructor or assigned by the
server).You should not wait for this event before connecting to other
peers if connection speed is important.
Emitted when a new data connection is established from a remote peer.
Emitted when a remote peer attempts to call you. The emitted
mediaConnection
is not yet active; you must first
answer the call (mediaConnection.answer([stream]);
). Then, you can listen for the
stream
event.
Emitted when the peer is destroyed and
can no longer accept or create any new connections. At this time,
the peer's connections will all be closed.
To be extra certain that peers clean up correctly, we recommend
calling peer.destroy()
on a peer when it is no longer
needed.
Emitted when the peer is disconnected from the signalling server,
either manually or because the
connection to the signalling server was lost. When a peer is
disconnected, its existing connections will stay alive, but the peer
cannot accept or create any new connections. You can reconnect to
the server by calling
peer.reconnect()
.
Errors on the peer are almost always fatal and will
destroy the peer. Errors from the underlying socket and
PeerConnections are forwarded here.
These come in the
following err.type
flavors:
The client's browser does not support some or all WebRTC features that you are trying to use.
You've already disconnected this peer from the server and can no longer make any new connections on it.
The ID passed into the Peer constructor contains illegal characters.
The API key passed into the Peer constructor contains illegal characters or is not in the system (cloud server only).
Lost or cannot establish a connection to the signalling server.
Unable to reach the server.
An error from the underlying socket.
The underlying socket closed unexpectedly.
Native WebRTC errors.
Close the connection to the server, leaving all existing data and media
connections intact.
peer.disconnected
will be
set to true
and the
disconnected
event will
fire.This cannot be undone; the respective peer object will no longer be
able to create or receive any connections and its ID will be forfeited
on the (cloud) server.
Attempt to reconnect to the server with the peer's old ID. Only disconnected peers can be reconnected. Destroyed peers cannot be reconnected. If the connection fails (as an example, if the peer's old ID is now taken), the peer's existing connections will not close, but any associated errors events will fire.
Close the connection to the server and terminate all existing
connections.
peer.destroyed
will be set to
true
.This cannot be undone; the respective peer object will no longer be
able to create or receive any connections, its ID will be forfeited on
the (cloud) server, and all of its data and media connections will be
closed.
The brokering ID of this peer. If no ID was specified in
the constructor, this will be
undefined
until the
open
event is emitted.
A hash of all connections associated with this peer, keyed by the remote peer's ID.We recommend keeping track of connections yourself rather than relying on this hash.
false
if there is an active connection to the PeerServer.
true
if this peer and all of its connections can no longer
be used.
Wraps WebRTC's DataChannel. To get one, use
peer.connect
or listen for the
connect
event.
data
is serialized by BinaryPack by default and sent to
the remote peer.
You can send any type of data, including objects, strings, and blobs.
Closes the data connection gracefully, cleaning up underlying DataChannels and PeerConnections.
Set listeners for data connection events.
Emitted when data is received from the remote peer.
Emitted when the connection is established and ready-to-use.
Emitted when either you or the remote peer closes the data connection.
A reference to the RTCDataChannel object associated with the connection.
The optional label passed in or assigned by PeerJS when the connection was initiated.
Any type of metadata associated with the connection, passed in by whoever initiated the connection.
This is true if the connection is open and ready for read/write.
A reference to the RTCPeerConnection object associated with the connection.
The ID of the peer on the other end of this connection.
Whether the underlying data channels are reliable; defined when the connection was initiated.
The serialization format of the data sent over the connection. Can
be binary
(default), binary-utf8
,
json
, or none
.
For data connections, this is always 'data'
.
The number of messages queued to be sent once the browser buffer is no longer full.
Wraps WebRTC's media streams. To get one, use
peer.call
or listen for the
call
event.
When receiving a call
event
on a peer, you can call .answer
on the media connection
provided by the callback to accept the call and optionally send your
own media stream.
A WebRTC media stream from
getUserMedia
.
Function which runs before create answer to modify sdp answer message.
Closes the media connection.
Set listeners for media connection events.
Emitted when a remote peer adds a stream
.
Emitted when either you or the remote peer closes the media connection.
Whether the media connection is active (e.g. your call has been answered). You can check this if you want to set a maximum wait time for a one-sided call.
Any type of metadata associated with the connection, passed in by whoever initiated the connection.
The ID of the peer on the other end of this connection.
For media connections, this is always 'media'
.
Provides a variety of helpful utilities.Only the utilities documented here are guaranteed to be present on
util
. Undocumented utilities can be removed without
warning. We don't consider these to be 'breaking changes.'
The current browser.
util.browser
can currently have the values 'firefox', 'chrome', 'safari', 'edge',
'Not a supported browser.', 'Not a browser.' (unknown WebRTC-compatible agent).
A hash of WebRTC features mapped to booleans that correspond to
whether the feature is supported by the current browser.Only the properties documented here are guaranteed to be present
on util.supports
.
True if the current browser supports media streams and PeerConnection.
True if the current browser supports DataChannel and PeerConnection.
True if the current browser supports binary DataChannels.
True if the current browser supports reliable DataChannels.