← All demos

P2P-only pub/sub

The same channel pub/sub as the Pub/Sub channels demo, but this page never makes a pub/sub call until a peer-to-peer data channel is open. The signaling WebSocket is only used to find the peer and set up the connection (SDP/ICE); subscriptions and messages travel peer to peer.

  1. Start publishing in the Publisher panel.
  2. Start subscribing here, or open the share link in another tab or device. Wait for the status to show P2P open.
  3. Send to a channel. Subscription changes made before the channel opens are applied once it does.

Why wait for the data channel? subscribe() and unsubscribe() send with WebSocket fallback enabled, so if no data channel is open they go through the signaling server. publishToChannel() and sendData() never fall back unless you pass allowFallback: true. This page waits for dataChannelOpen before subscribing, so nothing is relayed. As in the channels demo, channels are filtered by each subscriber, not by the publisher.

Publisher

Not publishing
    Messages sent0
    Viewers0
    P2P channels open0

    Subscriber

    Not connected

    Changes are sent to the publisher once the P2P data channel is open.

    Messages received0
    Channels0
    Key SDK calls in this demo
    // Publisher: data-only, joins the room from the URL
    await pub.connect();
    await pub.joinRoom({ room });
    await pub.announce({ streamID });
    pub.publishToChannel('alerts', { message: 'Hi' }); // data channels only, no fallback
    
    // Subscriber: only touch pub/sub once the P2P channel is open
    let p2pOpen = false;
    sub.addEventListener('dataChannelOpen', () => { p2pOpen = true; sub.subscribe(['general']); });
    sub.addEventListener('dataChannelClose', () => { p2pOpen = false; });
    sub.addEventListener('channelMessage', (e) => show(e.detail.channel, e.detail.data));
    await sub.connect();
    await sub.joinRoom({ room });
    await sub.view(streamID, { audio: false, video: false });
    if (p2pOpen) sub.subscribe('updates'); // otherwise queue it locally