Implement real-time presence tracking with PubNub
Step 1: Enable Presence Add-on
Step 2: Configure Presence Mode Choose between:
Step 3: Configure Channel Rules (if using "Selected channels only")
chat-room-* - All chat roomslobby - Specific channelgame-* - All game channelsImportant: Without configuring channel rules in Presence Management, presence will NOT work even if enabled in code.
const pubnub = new PubNub({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'unique-user-id'
});
// Subscribe with presence
pubnub.subscribe({
channels: ['chat-room'],
withPresence: true
});const pubnub = new PubNub({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'unique-user-id',
enableEventEngine: true // Better connection management
});
// Modern channel subscription API
const channel = pubnub.channel('chat-room');
const subscription = channel.subscription({
receivePresenceEvents: true
});
subscription.onPresence = (event) => {
console.log('Presence event:', event);
};
subscription.subscribe();const pubnub = new PubNub({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'unique-user-id',
heartbeatInterval: 60, // Send heartbeat every 60 seconds
presenceTimeout: 300 // Consider offline after 300 seconds
});| Use Case | Heartbeat Interval | Presence Timeout |
|---|---|---|
| Real-time chat | 30 | 120 |
| Gaming | 15 | 60 |
| IoT monitoring | 60 | 300 |
| Social presence | 60 | 300 |
| Battery-sensitive mobile | 120 | 600 |
When you subscribe with presence, PubNub creates a companion presence channel:
Original channel: chat-room
Presence channel: chat-room-pnpresYou don't subscribe to -pnpres directly - it's handled automatically.
Associate metadata with a user's presence:
// Set state when subscribing
pubnub.subscribe({
channels: ['chat-room'],
withPresence: true,
state: {
status: 'available',
mood: 'happy',
device: 'mobile'
}
});
// Update state later
await pubnub.setState({
channels: ['chat-room'],
state: {
status: 'busy',
mood: 'focused'
}
});
// Get user's current state
const result = await pubnub.getState({
channels: ['chat-room'],
uuid: 'other-user-id'
});// 1. Subscribe with presence
pubnub.subscribe({
channels: ['test-presence'],
withPresence: true
});
// 2. Check hereNow after subscribing
setTimeout(async () => {
const result = await pubnub.hereNow({
channels: ['test-presence'],
includeUUIDs: true
});
console.log('Occupancy:', result.channels['test-presence']?.occupancy);
console.log('UUIDs:', result.channels['test-presence']?.occupants);
}, 2000);| Problem | Solution |
|---|---|
| No presence events | Check channel rules in Presence Management |
| Occupancy always 0 | Ensure Presence add-on is enabled |
| Events delayed | Check heartbeat/timeout configuration |
| Duplicate join events | Ensure consistent userId across sessions |
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback
pnconfig = PNConfiguration()
pnconfig.subscribe_key = 'sub-c-...'
pnconfig.publish_key = 'pub-c-...'
pnconfig.uuid = 'unique-user-id'
pnconfig.heartbeat = 60
pnconfig.presence_timeout = 300
pubnub = PubNub(pnconfig)
class PresenceCallback(SubscribeCallback):
def presence(self, pubnub, presence):
print(f'Action: {presence.event}')
print(f'UUID: {presence.uuid}')
print(f'Occupancy: {presence.occupancy}')
pubnub.add_listener(PresenceCallback())
pubnub.subscribe().channels(['chat-room']).with_presence().execute()When using Access Manager (PAM), grant presence permissions:
// Server-side grant
await pubnub.grant({
channels: ['chat-room'],
authKeys: ['user-auth-token'],
read: true,
write: true,
manage: false,
ttl: 60
});
// Grant for presence channel specifically
await pubnub.grant({
channels: ['chat-room-pnpres'],
authKeys: ['user-auth-token'],
read: true,
ttl: 60
});tessl i pubnub/pubnub-presence@0.1.4