Build real-time applications with PubNub pub/sub messaging
Agent Success
Agent success rate when using this tile
94%
Improvement
Agent success rate improvement when using this tile compared to baseline
1.29x
Baseline
Agent success rate without this tile
73%
import PubNub from 'pubnub';
const pubnub = new PubNub({
publishKey: 'pub-c-...',
subscribeKey: 'sub-c-...',
userId: 'unique-user-id', // REQUIRED - persistent identifier
// Optional configuration
ssl: true, // Default: true (use HTTPS)
authKey: 'auth-token', // For Access Manager authentication
cipherKey: 'my-cipher-key', // For AES-256 message encryption
logVerbosity: false, // Enable debug logging
enableEventEngine: true // Recommended for better connection management
});from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
pnconfig = PNConfiguration()
pnconfig.publish_key = 'pub-c-...'
pnconfig.subscribe_key = 'sub-c-...'
pnconfig.uuid = 'unique-user-id' # REQUIRED
pnconfig.ssl = True # Default: True
pnconfig.auth_key = 'auth-token' # For Access Manager
pnconfig.cipher_key = 'my-cipher-key' # For encryption
pubnub = PubNub(pnconfig)import PubNub
let config = PubNubConfiguration(
publishKey: "pub-c-...",
subscribeKey: "sub-c-...",
userId: "unique-user-id"
)
config.authKey = "auth-token" // For Access Manager
config.cipherKey = "my-cipher-key" // For encryption
let pubnub = PubNub(configuration: config)import com.pubnub.api.PNConfiguration
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
val config = PNConfiguration(UserId("unique-user-id")).apply {
publishKey = "pub-c-..."
subscribeKey = "sub-c-..."
authKey = "auth-token" // For Access Manager
cipherKey = "my-cipher-key" // For encryption
}
val pubnub = PubNub(config)import com.pubnub.api.PNConfiguration;
import com.pubnub.api.PubNub;
PNConfiguration config = new PNConfiguration();
config.setPublishKey("pub-c-...");
config.setSubscribeKey("sub-c-...");
config.setUuid("unique-user-id"); // REQUIRED
config.setAuthKey("auth-token"); // For Access Manager
config.setCipherKey("my-cipher-key"); // For encryption
PubNub pubnub = new PubNub(config);// DON'T: Generate random UUID on each session
userId: crypto.randomUUID() // Creates billing/presence issues
// DON'T: Use undefined or empty
userId: '' // Will cause errors
userId: undefined // Will cause errors// DO: Generate once and persist
function getUserId() {
let userId = localStorage.getItem('pubnub_user_id');
if (!userId) {
userId = `user_${crypto.randomUUID()}`;
localStorage.setItem('pubnub_user_id', userId);
}
return userId;
}
// DO: Use authenticated user ID from your system
userId: authenticatedUser.id
// DO: Use device identifier for IoT
userId: `device_${deviceSerialNumber}`pubnub.addListener({
// Receive messages
message: (event) => {
console.log('Message:', event.message);
console.log('Channel:', event.channel);
console.log('Publisher:', event.publisher);
console.log('Timetoken:', event.timetoken);
},
// Connection status
status: (statusEvent) => {
console.log('Status category:', statusEvent.category);
console.log('Affected channels:', statusEvent.affectedChannels);
switch (statusEvent.category) {
case 'PNConnectedCategory':
console.log('Connected to PubNub');
break;
case 'PNReconnectedCategory':
console.log('Reconnected after disconnect');
break;
case 'PNDisconnectedCategory':
console.warn('Disconnected - will auto-reconnect');
break;
case 'PNNetworkDownCategory':
console.error('Network is down');
break;
case 'PNNetworkUpCategory':
console.log('Network restored');
break;
case 'PNAccessDeniedCategory':
console.error('Access denied - check auth token');
break;
}
},
// Presence events (if subscribed with presence)
presence: (presenceEvent) => {
console.log('Action:', presenceEvent.action); // join, leave, timeout
console.log('UUID:', presenceEvent.uuid);
console.log('Occupancy:', presenceEvent.occupancy);
},
// Signal events
signal: (signalEvent) => {
console.log('Signal:', signalEvent.message);
},
// Message actions (reactions, etc.)
messageAction: (actionEvent) => {
console.log('Action type:', actionEvent.data.type);
console.log('Action value:', actionEvent.data.value);
}
});from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
class MySubscribeCallback(SubscribeCallback):
def message(self, pubnub, message):
print(f'Message: {message.message}')
print(f'Channel: {message.channel}')
print(f'Publisher: {message.publisher}')
def status(self, pubnub, status):
if status.category == PNStatusCategory.PNConnectedCategory:
print('Connected')
elif status.category == PNStatusCategory.PNReconnectedCategory:
print('Reconnected')
elif status.category == PNStatusCategory.PNDisconnectedCategory:
print('Disconnected')
def presence(self, pubnub, presence):
print(f'Action: {presence.event}')
print(f'UUID: {presence.uuid}')
pubnub.add_listener(MySubscribeCallback())| Option | Description | Default |
|---|---|---|
publishKey | Key for publishing messages | Required |
subscribeKey | Key for subscribing to channels | Required |
userId | Unique client identifier | Required |
ssl | Use HTTPS connections | true |
authKey | Access Manager authentication token | None |
cipherKey | AES-256 encryption key | None |
logVerbosity | Enable debug logging | false |
enableEventEngine | Modern connection management | Varies |
heartbeatInterval | Presence heartbeat interval (seconds) | 300 |
presenceTimeout | Presence timeout (seconds) | 300 |
async function safePublish(channel, message) {
try {
const result = await pubnub.publish({ channel, message });
console.log('Published with timetoken:', result.timetoken);
return result;
} catch (error) {
console.error('Publish failed:', error.status);
if (error.status?.category === 'PNAccessDeniedCategory') {
// Refresh auth token and retry
await refreshAuthToken();
return pubnub.publish({ channel, message });
}
throw error;
}
}let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
pubnub.addListener({
status: (statusEvent) => {
if (statusEvent.category === 'PNDisconnectedCategory') {
reconnectAttempts++;
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
console.error('Max reconnection attempts reached');
// Notify user, show offline UI
}
} else if (statusEvent.category === 'PNConnectedCategory' ||
statusEvent.category === 'PNReconnectedCategory') {
reconnectAttempts = 0;
}
}
});import { useEffect, useRef } from 'react';
import PubNub from 'pubnub';
function ChatComponent({ userId, channel }) {
const pubnubRef = useRef(null);
useEffect(() => {
// Initialize
const pubnub = new PubNub({
publishKey: process.env.REACT_APP_PUBNUB_PUB_KEY,
subscribeKey: process.env.REACT_APP_PUBNUB_SUB_KEY,
userId
});
pubnubRef.current = pubnub;
// Add listener
const listener = {
message: (event) => {
// Handle messages
}
};
pubnub.addListener(listener);
// Subscribe
pubnub.subscribe({ channels: [channel] });
// Cleanup on unmount
return () => {
pubnub.removeListener(listener);
pubnub.unsubscribeAll();
};
}, [userId, channel]);
return (/* ... */);
}window.addEventListener('beforeunload', () => {
if (pubnub) {
pubnub.unsubscribeAll();
}
});