Skip to main content
Markdown

Presence in Laravel

Three ways to show people: a presence room lists who is in it to everyone in it (who is in the shop, who is viewing a document). A count says how many, at any size. And who is online is known across your whole app, for a dot on every avatar.

The browsers of Ann, Ben and Cara, each listing the three of them in the shop now, with their roles from the info of each member

A presence room: routes/channels.php​

// Who is in the shop, PresenceChannel( 'shop' ): everyone signed in, with their name and role.
Broadcast::channel( 'shop', fn ( User $user ) => [ 'name' => $user->name, 'role' => $user->role ] );

// The people of a room: those who may enter, or false.
Broadcast::channel( 'room.{room}', fn ( User $user, Room $room ) => $user->canEnter( $room ) ? [ 'name' => $user->name ] : false );
  • An array lets the user in, as the member info: what the others see of them, up to 4 KB, sealed with the room key. WordPlus Cloud lists the members without reading it.
  • true, in a room declared [ 'presence' => true ], lets them in with your profile (your users).
  • A member is the user, by their id as a string. A user with several tabs or devices is one member: they leave when their last connection does.
  • Up to 1,000 members are listed in full, with join and leave. Past that, the room counts them, and members() pages through them, up to 100,000.

The page​

const shop = rt.join( 'shop' );

const draw = () => list( [ ...shop.members ] ); // [ [ id, { name, role } ], … ]
shop.on( 'joined', draw );
shop.on( 'join', ( { id, info } ) => draw() );
shop.on( 'leave', ( { id } ) => draw() );

// Stepping out: leave the room, and the others see you go.
rt.leave( 'shop' );

A move to another server shows nobody leaving.

Counting​

[ 'count' => true ] gives a room a live count, without a list: product.on( 'count', ( n ) => … ), at most once a second. A presence room counts too.

Who is online, across your app​

Every page whose user your app vouched for makes that user online. They go offline 10 seconds after their last page closes, so a reload does not flicker.

rt.online.watch( [ 34, 43 ] ).on( 'change', ( { id, online, at } ) => dot( id, online ) );
rt.online.has( 34 ); // true or false, for a user watched
rt.online.on( 'count', ( n ) => showOnline( n ) );
Realtime::online()->has( 42 );   // and ->count(), ->list()

A page watches up to 1,000 users. A user who chose not to show their status is never online to anyone, in the boot() of a service provider:

use WordPlus\Realtime\Laravel\RealtimeServiceProvider;

RealtimeServiceProvider::hiddenUsing( fn ( $id ) => (bool) User::find( $id )?->hide_status );

Ready-made: who is online​

The Better Messages list of members, on a presence room, with a call button for each of the others. It is one element:

<wordplus-online room="shop" title="In the shop now" call="support:{pair}" type="video"></wordplus-online>
<wordplus-online-count room="product.7"></wordplus-online-count>
await rt.callScreen();   // loads the elements and the call screen, rt.ui() the elements without calls
  • call names the call the button of each row places: {pair} is the two user ids in order (support:34:42), {me} and {id} each one. Without it, the rows have no button.
  • Names and pictures come from the member info, then from your directory.
  • Its look is that of Better Messages, in a shadow root: your styles do not reach in, and its colours are CSS custom properties your page sets.

More, with Node and Python side by side: presence in depth.