Receive presence events
This guide shows you how to subscribe to a channel with presence events enabled and register a listener that receives them. Presence must be enabled on the keyset, and new keysets have it enabled by default. Once it's running, your application learns about arrivals, departures, and state changes as they happen, instead of polling Here Now on a timer.
When Access Manager is enabled, receiving presence events requires read permission on the channel, which also grants access to its -pnpres companion channel.
Enable presence events on a subscription
Create a subscription with the presence option turned on (named receivePresenceEvents in most SDKs), register a handler for it, then subscribe. PubNub delivers presence events through the same event listener you already use for messages and signals, with a dedicated presence handler.
- JavaScript
- Python
- Java
- Kotlin
- C#
- Go
- Swift
1const channel = pubnub.channel('chats.room1');
2const subscription = channel.subscription({ receivePresenceEvents: true });
3
4subscription.onPresence = (event) => {
5 console.log('Presence event:', event.action, event.uuid);
6};
7
8subscription.subscribe();
1subscription = pubnub.channel('chats.room1').subscription(with_presence=True)
2
3subscription.on_presence = lambda event: print('Presence event:', event.event, event.uuid)
4
5subscription.subscribe()
1Channel channel = pubnub.channel("chats.room1");
2Subscription subscription = channel.subscription(SubscriptionOptions.receivePresenceEvents());
3
4subscription.setOnPresence(result ->
5 System.out.println("Presence event: " + result.getEvent() + " " + result.getUuid()));
6
7subscription.subscribe();
1val subscription = pubnub.channel("chats.room1").subscription(SubscriptionOptions.receivePresenceEvents())
2
3subscription.onPresence = { presence -> println("Presence event: ${presence.event} ${presence.uuid}") }
4
5subscription.subscribe()
1Subscription subscription = pubnub.Channel("chats.room1").Subscription(SubscriptionOptions.ReceivePresenceEvents);
2
3subscription.onPresence += (Pubnub pn, PNPresenceEventResult e) =>
4 Console.WriteLine("Presence event: " + e.Event + " " + e.Uuid);
5
6subscription.Subscribe<object>();
1listener := pubnub.NewListener()
2
3go func() {
4 for presence := range listener.Presence {
5 fmt.Println("Presence event:", presence.Event, presence.UUID)
6 }
7}()
8
9pn.AddListener(listener)
10pn.Subscribe().Channels([]string{"chats.room1"}).WithPresence(true).Execute()
1let subscription = pubnub.channel("chats.room1").subscription(options: ReceivePresenceEvents())
2
3subscription.onPresence = { presenceChange in
4 print("Presence event: \(presenceChange)")
5}
6
7subscription.subscribe()
Most other SDKs document the same option and handler in the Publish/Subscribe section of their API reference, for example PHP or Ruby. The option name and the handler's field names both vary by SDK. Confirm both in your platform's reference before assuming the names above apply.
Tell events apart by action
Every presence event carries an action (or event) field naming which of the five subtypes fired: join, leave, timeout, state-change, or interval. Branch your handler on it instead of treating every presence event the same way:
1subscription.onPresence = (event) => {
2 switch (event.action) {
3 case 'join':
4 console.log(`${event.uuid} joined, occupancy ${event.occupancy}`);
5 break;
6 case 'leave':
7 case 'timeout':
8 console.log(`${event.uuid} left, occupancy ${event.occupancy}`);
9 break;
10 case 'state-change':
11 console.log(`${event.uuid} changed state:`, event.data);
12 break;
13 case 'interval':
14 console.log(`Occupancy is now ${event.occupancy}`);
15 break;
show all 17 linesleave and timeout both mean the client is gone. The difference is whether it unsubscribed deliberately or stopped responding. Refer to Presence events for what triggers each subtype, the full payload each one carries, and how a busy channel's interval mode changes which of them arrive.
If no events arrive
- Check Presence Management. If your keyset tracks selected channels only, the channel needs a rule that covers it and the event types you expect. Refer to Presence Management.
- Check the permission on the
-pnpreschannel. Confirm the client's token includes the required channel permission. A missing grant blocks the presence subscription the same way it blocks the channel's own messages, and surfaces as an access-denied status on your status listener. - Confirm the option is actually set. A subscription created without
receivePresenceEvents(or your SDK's equivalent) receives messages normally and no presence events at all, with no error to flag the difference.
Related tasks
- Presence events. Event subtypes, payloads, announce and interval modes, and heartbeat configuration.
- Get online users in a channel. Seed a roster with
Here Nowbefore switching to events to keep it current. - Set and get presence state. Attach the state that triggers a
state-changeevent. - Event listeners. The listener model this handler follows, and how its lifecycle differs from the subscription's.
- Presence. How presence data is enabled and delivered.