Skip to main content
Markdown

Rooms

A room carries events to every page that joined it. Your server sends to it (sending from your server), and pages may send to it too, as its rule allows (events from the page). A plugin declares the rooms it owns once, by pattern, with what they keep and allow, and decides who may join each.

Names​

  • Up to 200 characters of A-Z a-z 0-9 _ - = @ , . ; :. order:42 and chat:34:42 are the usual shape.
  • The rooms of each site are its own. The order:42 rooms of two sites never meet.
  • They are separate from the Pusher-compatible API channels. A Pusher client cannot join them.

Owning rooms​

add_action( 'plugins_loaded', function () {
// The order of Ben: him, and the shop staff.
wordplus_realtime()->room( 'order:{id}', function ( $user_id, array $p ) {
return $user_id > 0 && ( my_shop_customer_of( (int) $p['id'] ) === $user_id || user_can( $user_id, 'manage_woocommerce' ) );
}, array( 'history' => 20 ) );

// The chat of Ann and Ben: those two only. They send messages, typing and read ticks.
wordplus_realtime()->room( 'chat:{a}:{b}', function ( $user_id, array $p ) {
return in_array( (string) $user_id, array( $p['a'], $p['b'] ), true );
}, array( 'presence' => true, 'history' => 50, 'emit' => array( 'message', 'typing', 'read' ), 'webhook' => array( 'message' ) ) );

// The page of the product: anyone, signed in or not, and how many are looking.
wordplus_realtime()->room( 'product:{id}', null, array( 'public' => true, 'count' => true ) );
} );
  • {name} matches one or more characters other than : and ., as few as the rest of the pattern allows. The rule gets them as $p['name'].
  • The rule with the most characters of its own wins. On a tie, the one declared first. A room no rule matches is refused with no_rule.
  • $user_id is the site user: the id of a WordPress user, a visitor negative id a plugin gives (wordplus_realtime_visitor_id, as Better Messages does for its guests), or 0 for nobody.
  • The answer is false, true, or an array for that user: info, what the members of a presence room see of them (their name and picture by default), and emit or readOnly to narrow what they may send.
  • When it runs: the page asks for every room it joins in the same moment in one request, and keeps each token until 10 minutes before it expires, across reconnects and moves. Your rule runs when a page first joins and when its token is renewed (6 hours by default, the filter wordplus_realtime_token_ttl, at most a day).

What a room keeps and allows​

OptionDefault
presenceoffIts members are listed with their info. join and leave tell the others (presence)
countoffA live count of who is in it, at any size, without a list. Presence counts too
historynoneEvents kept for pages that reconnect: a number, up to 1,000, for 5 minutes. Or array( 'last' => 50, 'days' => 0.002 ) for less (0.002 of a day is about 3 minutes)
emitnoneEvents pages may send to the room: names, or '*' for any (events from the page)
webhooknoneWhich of the page events your server gets too (webhooks)
publicoffAnyone may join, signed in or not. A public room with no rule has its grant in every page, which a cache may keep. Not sealed
sealonIts events, its member info and its history are sealed with the room key (encryption)

The options travel in the room token, signed by the site with the room name, so WordPlus Cloud enforces them and nothing is set in two places.

Joining in the browser​

Your script depends on the SDK handle, and the page gets its settings in window.wordplusRealtimeConfig:

wp_enqueue_script( 'my-shop', plugins_url( 'shop.js', __FILE__ ), array( wordplus_realtime()->script() ), '1.0.0', true );
const rt = wordplusRealtimeClient.page();   // null on a site without credentials

const order = rt.join( 'order:42' );
order.on( 'updated', ( data, meta ) => refresh( data ) ); // meta: { from, id, at, replayed? }
order.on( 'joined', () => console.log( 'in' ) );
order.on( 'error', ( e ) => console.warn( e.code ) ); // forbidden, no_rule, full, expired …

order.state; // joining, joined, failed, left
rt.leave( 'order:42' );
  • page() is the rooms of the page, the same for the code of every plugin and the call screen. join() gives the same room for the same name.
  • Events reach a listener opened: you never handle sealed values.
  • meta.from is the user who sent it from a page, as the site vouched for them, or nothing for your server. meta.id and meta.at are the kept event id and time.
  • The events of the room itself are joined, join, leave, count and error, and connected, disconnected and moved on rt. Nobody can send them.
  • rt.on( 'error', fn ) hears the connection refused, with { code }: not_included, not_licensed, wrong_origin … (errors).

Ann marks order 42 of Ben as paid in her browser, and the order page of Ben shows Paid at once

History, and nothing lost on a reconnect​

A room keeps its events for 5 minutes at most, for recovery. Your plugin keeps its own records, such as the messages of a chat, from the webhook.

  • Kept per room, as its rule says: every kept event has an id, rising within the room, and the time it was sent. Events over 64 KB are sent but not kept. volatile ones are never kept.
  • A reconnect gets what it missed: a connection back within the history span gets the missed events first, in order, with meta.replayed, then the new ones, across the WordPlus Cloud servers and moves.
  • Paging back: at most 100 a page.
const { events, more } = await order.history( { limit: 50 } );                 // the newest 50, oldest first
const older = await order.history( { before: events[ 0 ].id, limit: 50 } );
  • Your server reads and erases it the same way: wordplus_realtime()->in( $room )->history() and ->forget( $id ) (sending).

One connection for the whole browser​

Every tab and every plugin of a browser rides one connection, the one the WordPlus plugins ride: Better Messages, Easy Stream and the rest. A tab hears only the events of its own rooms. An event a tab sent itself, or one your server sent with except naming that tab, does not come back to it.

Limits​

See limits: 1,000 rooms a connection, events of up to 1 MB, and 100,000 members a presence room.