---
sidebar_position: 3
---

# Presence

A presence channel lists who is on it to everyone on it, and says when someone arrives and leaves.

![Three browsers, Ann’s, Ben’s and Cara’s, each listing the three of them in the shop now, with their roles from each member’s info](/img/apps/presence-shop.webp)

**Node**

```ts
realtime.channel( 'presence-room-', async ( user, channel ) => {
    if ( user === null || !( await mayEnter( user, channel ) ) ) return false;
    return { info: { name: await nameOf( user ), role: 'agent' } };   // what the others see; your profile's name by default
} );
```

**PHP**

```php
$realtime->channel( 'presence-room-', function ( $user, $channel ) {
    if ( null === $user || ! may_enter( $user, $channel ) ) {
        return false;
    }
    return [ 'info' => [ 'name' => name_of( $user ), 'role' => 'agent' ] ];   // what the others see; your profile's name by default
} );

// Laravel: routes/channels.php, where an array is the member's info. PresenceChannel( 'room.7' ) is presence-room.7 here.
Broadcast::channel( 'room.{id}', fn ( User $user, string $id ) => $user->canEnter( $id ) ? [ 'name' => $user->name, 'role' => 'agent' ] : false );
```

**Python**

```python
def may_enter_room(user, channel):
    if user is None or not may_enter(user, channel):
        return False
    return {"info": {"name": name_of(user), "role": "agent"}}   # what the others see; your profile's name by default

realtime.channel("presence-room-", may_enter_room)
```

- A member is the asking user (`id`, their id as a string), unless the answer names another `id`: a visitor you know by a session id, for example.
- Nobody, without an `id` in the answer, is refused.
- `info` is at most 1 KB, sealed with the channel's key: WordPlus Cloud lists members without reading it.

```ts
const room = rt.subscribe( 'presence-room-7' );
room.on( 'realtime:subscribed', () => draw( room.members() ) );          // [ { id, info } ]
room.on( 'realtime:member_added', ( member ) => add( member ) );          // { id, info }
room.on( 'realtime:member_removed', ( member ) => remove( member.id ) );
```

- A user with several tabs or devices is one member: they leave when their last connection does.
- A move to another server shows nobody leaving.
- 1,000 members a channel, the first 100 listed when subscribing; `room.memberCount` is the whole count.

In React, `usePresence( 'presence-room-7' )` gives the members and updates with them ([React](react.md)).
