Skip to main content
Markdown

Channels

A channel is a name browsers listen to. Your server publishes to it, and browsers on private and presence channels can send each other events too.

Names and kinds​

Up to 200 characters of A-Z a-z 0-9 _ - = @ , . ;. The start of the name says its kind, as Pusher's do:

KindStarts withWho may listenSealed
Publicanything elseanyone with your app's keyno: anything there is public
Privateprivate-whoever your server lets inyes, with the channel's key
Presencepresence-whoever your server lets in, listed to everyone on ityes, with the channel's key

A channel lives within your app: another app's orders is another channel. private-encrypted-… isn't taken.

Owning a channel​

Your server owns names by their start, and answers for each user who asks:

realtime.channel( 'private-orders-', async ( user, channel ) => {
const order = await findOrder( channel.slice( 'private-orders-'.length ) );
return order !== null && order.userId === user;
} );
  • user is the asking user's id, or null (None) for nobody.
  • Answer false (or null) for no, true for yes, or for presence { id, info } (presence).
  • In Node the callback may be async. In Python it is a plain function, which may query your database the usual way.
  • The longest prefix that fits decides. A private or presence channel nobody owns is refused (forbidden).
  • The browser asks for every channel it subscribes to in the same moment in one request, and keeps the token across reconnects and moves: your callback runs when a page first subscribes and when its token is renewed (6 hours by default).

Listening​

const orders = rt.subscribe( 'private-orders-42' );
orders.on( 'updated', ( data ) => refresh( data ) );
orders.on( 'realtime:subscribed', () => console.log( 'listening' ) );
orders.on( 'realtime:error', ( e ) => console.warn( e.code ) ); // forbidden, expired, auth_failed …

rt.unsubscribe( 'private-orders-42' );
  • subscribe() gives the same subscription for the same name.
  • Every tab of the browser rides one connection, each with its own subscriptions.
  • Events reach a listener opened: you never handle sealed values.
  • The page's own events are named realtime:…, which nobody can publish.

Publishing​

await realtime.publish( 'private-orders-42', 'updated', { status: 'paid' } );
await realtime.publish( [ 'private-orders-42', 'orders' ], 'updated', { id: 42 } );
await realtime.publish( 'presence-room-7', 'message', { text }, { except: tab } ); // not back to the tab that sent it

More in publishing.

Client events​

Browsers on a private or presence channel can send each other events named client-…, sealed like the rest:

const room = rt.subscribe( 'presence-room-7' );
await room.trigger( 'client-typing', { on: true } );
room.on( 'client-typing', ( data, { user_id } ) => showTyping( user_id, data.on ) );

A tab doesn't hear its own. At most 10 a second a browser, 10 KB each. They don't go through your server: check anything that matters on your server instead.