How can you detect when a user goes online or offline, or how do you know whether a client device is connected and when it disconnects? PubNub presence lets you track who is connected to your channels in real-time and alerts you when their connection status changes.

Please note that how the presence options are displayed in the portal has changed since this video was recorded, however the options retain the same names and functionality.

The presence system is very flexible and enables use cases such as:

  • Monitoring when users join or leave a chat conversation
  • Detecting when a user is online or offline
  • Determining whether an IoT device is connected and available
  • Counting how many clients are connected to a channel (channel occupancy count)

You can also define some state information (metadata) to accompany the client’s presence that will be received by all interested recipients; for example, although the client’s presence is ‘online,’ the User can choose to set their custom status as ‘away’ or ‘do not disturb.’

To enable PubNub presence, log into the admin portal, navigate to the app and keyset you want to enable presence on, select the 'Presence' option from the Configuration section, and toggle the presence switch in that keyset’s configuration screen:

Portal Configuration: Presence Enable

You will be prompted to confirm that you want to enable presence.

Be aware that enabling presence can result in significantly more transactions, especially for those on a transaction-based pricing plan. To control the number of transactions, you can use the ‘Presence management’ feature, explained later in this article.

Portal Configuration: Presence Enable Confirm

Be sure to save any changes whenever you make modifications to your keyset configuration.

Portal Configuration: Presence Confirm Changes

Announce Mode

Once enabled, PubNub will automatically generate presence events as clients (users or devices) subscribe to or unsubscribe from any channel.

When a client subscribes to a channel, it will generate a join event:

{
  "channel": "<name of channel that was joined>",
  "action": "join",
  "occupancy": 2, //  Channel occupancy
  "uuid": "<userid of client who joined>", 
  "timetoken”: "<When the join occurred>"
}

When a client unsubscribes from a channel, it will generate a leave event:

{
  "channel": "<name of channel that was left>",
  "action": "leave",
  "occupancy": 1, //  Channel occupancy
  "uuid": "<userid of client who left>", 
  "timetoken": “<When the leave occurred>"
}

Consider a web client connected to a channel, and the user forcibly closes the tab instead of allowing the client to unsubscribe:

If the client does not explicitly unsubscribe but is detected as not being present after a period of time (300 seconds by default), a timeout event is triggered:

{
  "channel": "<name of channel connection that timed out>",
  "action": "timeout",
  "occupancy":1, //  Channel occupancy
  "uuid": "<userid of client who timed out>", 
  "timetoken": "<When the timeout occurred>"
}

Generate Leave on TCP FIN or RST

Instead of waiting for the timeout event in the above scenario, another option is to detect at the network level when a client leaves the channel. By enabling the ‘Generate Leave on TCP FIN or RST’ option on the keyset, forcibly closing the browser tab in this scenario will now generate a leave event which is fired immediately, instead of a timeout event.

Portal Configuration: Presence Generate Leave TCP FIN RST

Debounce

Sometimes, clients will rapidly join and leave channels, either because of network issues or your application design. To avoid excessive join and leave events, specify a debounce value in seconds. After a client generates a join event, they will not be allowed to generate another join event for another two seconds, for example.

Portal Configuration: Presence Debounce

Interval Mode

Announce Max

The join and leave events will triggered immediately as long as the number of clients in the channel remains below the ‘Announce Max’ setting, which defaults to 20.

Portal Configuration: Presence Announce Max

As the number of occupants in a channel increases, the number of join and leave events will also increase, but at some point, it becomes wasteful for a client to attempt to maintain all these events in real-time. Consider a group chat with 200 participants; does the client need to update the online state of every one of those participants as they go online or offline? It would be more information than the human user could keep track of.

You can configure Announce Max between 1 and 100. Once the number of clients in a channel exceeds ‘Announce Max,’ the join, leave, and timeout events are no longer generated but are replaced by the interval event:

{
  "channel: "<name of channel the event applies to>",
  "action": "interval",
  "occupancy": 4, //  Channel occupancy
  "timetoken": "<When the interval event occurred>"
}

Interval

You can configure how often the interval event will fire by modifying the Interval configuration option. Values between 10 seconds to 300 seconds (5 minutes) are allowed.

Portal Configuration: Presence Interval

The interval event will only notify you of the channel occupancy unless you enable ‘Presence Deltas’

Presence Deltas

Portal Configuration: Presence Deltas

With ‘Presence Deltas’ enabled, the interval event will also include information about which users have joined or left the channel since the previous interval event.

{
  "channel": "<name of channel the event applies to>",
  "action": "interval",
  "occupancy": 3, //  Channel occupancy
  "join": ["member4"],
  "leave": ["member3"],
  "timetoken": "<When the interval event occurred>"
}

Other Settings

Active Notice Channel

You might not be interested in how many clients are connected to a channel or who those clients are, but instead, you might only care about whether or not anybody is subscribed to a channel. If a channel has 0 subscribers, it is considered inactive. A channel with 1 or more subscribers is considered active.

You can register to receive notice when a channel becomes ‘active’ or ‘inactive’ by specifying an ‘Active Notice Channel’.

Portal Configuration: Presence Active Notice Channel

If specified, you will receive messages on this channel (in this example, the channel name that receives the messages is "notice_channel"):

{
  "channel": "<name of the channel which has become active or inactive>",
  "status": "active",  //  or inactive
  "precise_timestamp": "<When the interval event occurred>"
}

Note that active events are sent as soon as the channel occupancy rises above 0, but channel inactive events will only fire if the channel has an occupancy of 0 for 300 seconds or more.

Stream Filtering

The option to disable stream filtering is retained for legacy reasons, and developers will gain little benefit from turning this setting off. Stream Filtering will include Presence metadata in events published to the presence channels, allowing client filters to be applied to these presence events. Disabling stream filtering does not reduce the number of presence events; it only allows the client to filter out which events they receive - to reduce the number of presence events you should use Presence Management, explained later in this article.

Portal Configuration: Presence Stream Filtering

Webhooks

Previously, the keyset configuration page allowed you to specify multiple webhooks that would be fired when any of the following events occurred:

  • join event fired
  • leave event fired
  • timeout event fired
  • interval event fired
  • state-change event fired
  • channel active or channel inactive event fired.

These webhooks are no longer part of the keyset configuration but have been migrated to the Events & Actions feature. Webhooks will not be discussed in the scope of this article, but for more information, please refer to the Webhook Payload action section of the Events & Actions documentation.

State Change

If you want to exchange some metadata associated with the client’s presence, the best way to achieve that is with the Presence State feature. For example, although the join and leave events discussed previously will tell you whether the client is online or offline, that does not let you know if the user is ‘busy’ or ‘do not disturb.’

A client can use the PubNub SDK to set a custom state on a specific channel or channel group. Once set, this state is propagated to other clients and received as a state-change event.

{
  "channel": "<name of channel associated with the state change>",
  "uuid": "<ID of client the state applies to>"
  "action": "state-change",
  "state": {<JSON Object defining the state>}
  "occupancy": 3, //  Channel occupancy
  "timetoken": “<When the state change occurred>"
}

State change is very flexible and can be used to exchange any serializable data; for example, our collaboration demo uses presence state to notify listeners when a draw event occurs, allowing a collaborative drawing application, with doodles being shown to all viewers in real time

"state": {"x": 5, "y": 10, "color":"#FFFF00"}  //  Example state payload for a drawing application

The only caveat with state-change events is that they do not persist, so they should only be used for ephemeral data or data each client is expected to keep track of.

Controlling which Events you receive using Presence Management

As mentioned earlier, it is easy for the number of presence events to get very large as your user base grows. To give you greater control over which events fire on any specified channel, we have introduced the self-service ‘Presence Management’ tool, which allows you to create rules that control which presence events will fire:

Portal Configuration: Presence Management

You can access the tool from the left-hand menu under the ‘BizOps Workspace’ section.

Please refer to the Presence Management documentation for a full description of how to configure your management rules, but in summary:

  1. Create a new rule; you can have multiple rules to fully define the presence events you want to trigger for your application.
  2. Specify the events you want this rule to control, including join, leave, timeout, state-change, and interval. This article has covered what these rules are and when they fire.
  3. Specify a wildcard pattern to define the channel or channel groups that this rule applies to; for example personal-* will apply to all channels that start personal-
  4. Click ‘Create’ and define the order in which your rules should apply.

Presence Management through the PubNub API

You can receive presence events through any of our SDKs. This article has focused chiefly on Presence events, which are received through the SDK event listener, but our APIs also support additional functions to determine who is listening on a specific channel (here now) and where a particular user is subscribed (where now)

In JavaScript, the hereNow API can be called as follows to determine who is subscribed to the specified channel:

1 2 3 4 5 6 7 8 9 10 try { const result = await pubnub.hereNow({ channels: ["my_channel"], includeState: true, includeUUIDs: true }); console.log(“total occupancy: “ + result.totalOccupancy) } catch (status) { console.log(status); }

More Resources

Presence is one of the most valuable and flexible features of the PubNub platform. Knowing exactly who is online and having that status update in real-time has enabled our customers to build some intriguing solutions over the years.

  • Our Presence Basics documentation is a good starting point to understand the concepts of Presence.
  • Our Subscribe documentation will give examples showing how to subscribe to a channel with presence enabled and refer to the SDK-specific documentation for API examples showing how to add a listener callback for presence events (e.g., this page for our JavaScript SDK).
  • To get more hands-on, most of our tutorials will include presence, and a good starting place for new developers is our Getting Started tutorial, which covers several programming languages. The tutorials will also cover other presence features, such as the ‘here now’ API, to determine who is listening on a channel.

Finally, if you need help or support, feel free to reach out to our dedicated pubnub support team or email our developer relations team at devrel@pubnub.com