WebRTC rooms for the browser: send data and share media straight from one peer to the others.
- Rooms. Join a room by name, and get a participant for every other peer in it, each with its own
RTCPeerConnection. - Data channels.
senda string or binary data to one participant or the whole room. Messages sent before the channel opens wait and go out in order. - Media. Share a
MediaStreamwhen you join or at any time later: the connection renegotiates by itself, and offers that cross are resolved with the perfect negotiation pattern. - Your signaling. socket.io with the client version that matches your server,
BroadcastChannelbetween tabs with no server at all, or your own in two methods. - Small. No dependencies, typed events, ES modules, written in strict TypeScript.
📖 Documentation · Live demo · Examples · Migrating from v3
npm install peer-datapeer-data runs in current Chrome, Edge, Firefox and Safari; its tests run in Chromium, Firefox and WebKit.
Two tabs of the same page talk with no server, through BroadcastChannel:
import { BroadcastChannelSignaling, PeerData } from 'peer-data';
const peer = new PeerData(new BroadcastChannelSignaling());
const room = peer.connect('lobby');
room.on('participant', (participant) => {
participant.on('message', (data) => console.log(participant.id, 'says', data));
participant.send('hello');
});Open it in two tabs, and each logs the other's hello. Across browsers and devices, signal through a server instead:
import { io } from 'socket.io-client';
import { PeerData, SocketChannel } from 'peer-data';
const peer = new PeerData(new SocketChannel(io('https://signaling.example.com')), {
configuration: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] },
});examples/socket/server.ts is a small signaling server on socket.io 4 to start from.
Pass a stream when you join, and every participant receives its tracks:
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const room = peer.connect('call', stream);
room.on('participant', (participant) => {
participant.on('track', ({ streams: [remote] }) => {
if (remote) video.srcObject = remote;
});
});participant.addStream(stream) shares one later. Either side can add media at any time.
room.disconnect() tells the others and closes every connection in the room; peer.close() leaves every room.
A participant fires disconnected once when it leaves, its connection fails, or you call participant.close().
v4 has no EventDispatcher: PeerData takes the signaling directly, and SocketChannel takes a socket you create.
// v3
const dispatcher = new EventDispatcher();
const peerData = new PeerData(dispatcher, servers, constraints);
const signaling = new SocketChannel(dispatcher, 'http://localhost:8080');
// v4
const peerData = new PeerData(new SocketChannel(io('http://localhost:8080')), {
configuration: servers,
channel: constraints,
});The messages between peers keep their v3 shape, so v3 signaling servers still route them. MIGRATION.md maps every v3 call to its v4 form and lists the behaviour changes.
Bug reports and pull requests are welcome: see CONTRIBUTING.md.
MIT, see LICENSE.