Application and Listener Setup
In this document you'll learn how to set up your app and add a generic event listener that can be used for any use case.
Concepts
There are two important concepts that require your attention before you start setting up your application.
UUIDs
You can use one UUID to represent a user on all their devices, or use one UUID per client. If you allow a user to connect from multiple devices simultaneously, use the same UUID for each device, as PubNub features such as Presence, which determine's a user's online status, rely on UUIDs.
For client-side SDKs, the client should obtain the user's UUID from the server after the user successfully logs in to your system. Please read User Identity & UUID Management for more details.
Access Control
Access Manager provides application-layer security through Role-Based Access Control (RBAC) to your PubNub implementation. If you think you'll need RBAC in the future, please plan ahead. PubNub provides you with a secret key meant to be used by your servers for any admin and secure interactions with PubNub. Refer to Access Control for more info.
Application Setup
Before you can use PubNub in your app, you'll need to install (or include) a PubNub SDK in your app, initialize (instantiate) a PubNub object, and add listeners for all the events that happen on the PubNub network.
Include or install
Each platform and language has different, and sometimes several, ways of getting the PubNub SDK into your app.
// Using the PubNub CDN, add the SDK to your web application.
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.29.9.js"></script>
// If you're using the PubNub Node.js SDK, use the command `npm install pubnub`
To integrate PubNub into your Xcode project using Swift Package Manager, specify it in the dependencies list of your Package.swift file:
dependencies: [
.package(url: "https://github.com/pubnub/swift.git", from: "3.1.0")
]
Or, in Xcode, navigate to File > Swift Packages > Add Package Dependency, then enter https://github.com/pubnub/swift.git
for the package repository URL. You can use defaults for the remaining steps.
CocoaPods is the easiest way to install the PubNub Objective-C SDK in your iOS app. (Check the Objective-C SDK documentation for other installation options, and the latest SDK version.)
In the project's root folder, create a Podfile using
pod init
(requires CocoaPods 1.0.0 or above).Open
Podfile
in an editor. Addpod "PubNub", "~> 4"
to thetarget
section, and replaceMyObjcProject
with your project name.platform :ios, '9.0' # (or '10.0')
target 'MyObjcProject' do
use_frameworks!
pod "PubNub", "~> 4"
endIn the same directory as the Podfile, enter the command:
pod install
.In Xcode, open the workspace (
.xcworkspace
) file, not the project (.xcodeproj
) file.
You can include the PubNub Android SDK using Gradle.
Insert the PubNub
implementation group
dependency at the end of thedependencies
section inbuild.gradle (Module: app)
under the Gradle Scripts folder of your project. Your list of existing dependencies may differ.dependencies {
// some existing dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
// add PubNub Android-Java SDK here at the bottom
implementation group: 'com.pubnub', name: 'pubnub-gson', version: '4.+'
}Click Sync Now in the top right of the Android Studio file editor window.
In your project's manifests folder, add the following permissions to
AndroidManifest.xml
:<manifest>
...existing content...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
You can also use Maven, or download the latest version of the Android SDK JAR file from the Android SDK documentation to add to your IDE or build process.
For the latest version, refer to the C# SDK documentation.
To install the many flavors of the C# SDK, refer to the following links for different package managers:
C# 3.5/4.0/4.5/4.61: https://www.nuget.org/packages/Pubnub/4.6.0.0
Universal Windows: https://www.nuget.org/packages/PubnubUWP/4.6.0.0
Xamarin.Android, Xamarin.iOS, and .NET Core/.NET Standard: https://www.nuget.org/packages/PubnubPCL/4.6.0.0
The simplest way to install the PubNub Python SDK is with pip
:
pip install 'pubnub>=4.6.0'
Initialize a PubNub object
Now, initialize (instantiate) a PubNub object using your own publish and subscribe keys. If you don't yet have a PubNub account, go to the Admin Portal to create your free account and API keys. You'll use them in this and all other sample code that uses the myPublishKey
and mySubscribeKey
placeholders.
You don't have to create a new instance of the PubNub object for each message you send. When you instantiate PubNub, it creates TCP connections in a way that do not get garbage collected between uses such as publish, subscribe, here-now, etc.
<script type="text/javascript">
var pubnub = new PubNub({
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
uuid: "theClientUUID"
});
<script>
import PubNub
var pnconfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey"
)
pnconfig.uuid = "theClientUUID"
let pubnub = PubNub(configuration: pnconfig)
#import <PubNub/PubNub.h>
PNConfiguration *pnconfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
pnconfig.uuid = "theClientUUID";
PubNub *pubnub = [PubNub clientWithConfiguration:pnconfig];
import com.pubnub.api;
PNConfiguration pnconfig = new PNConfiguration();
pnconfig.setPublishKey("myPublishKey");
pnconfig.setSubscribeKey("mySubscribeKey");
pnconfig.setUuid("theClientUUID");
PubNub pubnub = new PubNub(pnconfig);
using PubnubApi;
PNConfiguration pnconfig = new PNConfiguration();
pnconfig.PublishKey = "myPublishKey";
pnconfig.SubscribeKey = "mySubscribeKey";
pnconfig.Uuid = "theClientUUID";
Pubnub pubnub = new Pubnub(pnconfig);
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
pnconfig = PNConfiguration()
pnconfig.publish_key = "myPublishKey"
pnconfig.subscribe_key = "mySubscribeKey"
pnconfig.uuid = "theClientUUID"
pubnub = PubNub(pnconfig)
At this point, you can start calling PubNub operations using the pubnub
object.
Add a Listener
Messages and events are received in your app using a listener. This listener allows a single point to receive all messages, signals, and events.
Each type of message or event has its own handler to receive them where you implement your custom app logic to do something useful with the received data.
The following handlers are available to you:
pubnub.addListener({
message: function(m) {
// handle message
var channelName = m.channel; // The channel to which the message was published
var channelGroup = m.subscription; // The channel group or wildcard subscription match (if exists)
var pubTT = m.timetoken; // Publish timetoken
var msg = m.message; // The Payload
var publisher = m.publisher; //The Publisher
},
presence: function(p) {
// handle presence
var action = p.action; // Can be join, leave, state-change, or timeout
var channelName = p.channel; // The channel to which the message was published
var occupancy = p.occupancy; // Number of users subscribed to the channel
var state = p.state; // User State
var channelGroup = p.subscription; // The channel group or wildcard subscription match (if exists)
var publishTime = p.timestamp; // Publish timetoken
var timetoken = p.timetoken; // Current timetoken
var uuid = p.uuid; // UUIDs of users who are subscribed to the channel
},
signal: function(s) {
// handle signal
var channelName = s.channel; // The channel to which the signal was published
var channelGroup = s.subscription; // The channel group or wildcard subscription match (if exists)
var pubTT = s.timetoken; // Publish timetoken
var msg = s.message; // The Payload
var publisher = s.publisher; //The Publisher
},
objects: (objectEvent) => {
var channel = objectEvent.channel; // The channel
var channelGroup = objectEvent.subscription; // The channel group
var timetoken = objectEvent.timetoken; // The event timetoken
var publisher = objectEvent.publisher; // The UUID that triggered this event
var event = objectEvent.event; // The event name that occurred
var type = objectEvent.type; // The event type that occurred
var data = objectEvent.data; // The event data that occurred
},
messageAction: function(ma) {
// handle message action
var channelName = ma.channel; // The channel to which the message was published
var publisher = ma.publisher; //The Publisher
var event = ma.message.event; // message action added or removed
var type = ma.message.data.type; // message action type
var value = ma.message.data.value; // message action value
var messageTimetoken = ma.message.data.messageTimetoken; // The timetoken of the original message
var actionTimetoken = ma.message.data.actionTimetoken; // The timetoken of the message action
},
file: function (event) {
const channelName = event.channel; // Channel to which the file belongs
const channelGroup = event.subscription; // Channel group or wildcard subscription match (if exists)
const publisher = event.publisher; // File publisher
const timetoken = event.timetoken; // Event timetoken
const message = event.message; // Optional message attached to the file
const fileId = event.file.id; // File unique id
const fileName = event.file.name;// File name
const fileUrl = event.file.url; // File direct URL
},
status: function(s) {
var affectedChannelGroups = s.affectedChannelGroups; // The channel groups affected in the operation, of type array.
var affectedChannels = s.affectedChannels; // The channels affected in the operation, of type array.
var category = s.category; //Returns PNConnectedCategory
var operation = s.operation; //Returns PNSubscribeOperation
var lastTimetoken = s.lastTimetoken; //The last timetoken used in the subscribe request, of type long.
var currentTimetoken = s.currentTimetoken; //The current timetoken fetched in the subscribe response, which is going to be used in the next request, of type long.
var subscribedChannels = s.subscribedChannels; //All the current subscribed channels, of type array.
},
});
// Create a new listener instance
let listener = SubscriptionListener()
// Add listener event callbacks
listener.didReceiveSubscription = { event in
switch event {
case let .messageReceived(message):
print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
case let .connectionStatusChanged(status):
print("Status Received: \(status)")
case let .presenceChanged(presence):
print("Presence Received: \(presence)")
case let .subscribeError(error):
print("Subscription Error \(error)")
default:
break
}
}
// Start receiving subscription events
pubnub.add(listener)
// Listener's class should conform to `PNEventsListener` protocol
// in order to have access to available callbacks.
// Adding listener.
[pubnub addListener:self];
// Callbacks listed below.
- (void)client:(PubNub *)pubnub didReceiveMessage:(PNMessageResult *)message {
NSString *channel = message.data.channel; // Channel on which the message has been published
NSString *subscription = message.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSNumber *timetoken = message.data.timetoken; // Publish timetoken
id msg = message.data.message; // Message payload
NSString *publisher = message.data.publisher; // Message publisher
}
- (void)client:(PubNub *)pubnub didReceiveSignal:(PNSignalResult *)signal {
NSString *channel = message.data.channel; // Channel on which the signal has been published
NSString *subscription = message.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSNumber *timetoken = message.data.timetoken; // Signal timetoken
id msg = message.data.message; // Signal payload
NSString *publisher = message.data.publisher; // Signal publisher
}
- (void)client:(PubNub *)pubnub didReceiveMessageAction:(PNMessageActionResult *)action {
NSString *channel = action.data.channel; // Channel on which the message has been published
NSString *subscription = action.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSString *event = action.data.event; // Can be: added or removed
NSString *type = action.data.action.type; // Message action type
NSString *value = action.data.action.value; // Message action value
NSNumber *messageTimetoken = action.data.action.messageTimetoken; // Timetoken of the original message
NSNumber *actionTimetoken = action.data.action.actionTimetoken; // Timetoken of the message action
NSString *uuid = action.data.action.uuid; // UUID of user which added / removed message action
}
- (void)client:(PubNub *)pubnub didReceivePresenceEvent:(PNPresenceEventResult *)event {
NSString *channel = message.data.channel; // Channel on which presence changes
NSString *subscription = message.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSString *presenceEvent = event.data.presenceEvent; // Can be: join, leave, state-change, timeout or interval
NSNumber *occupancy = event.data.presence.occupancy; // Number of users subscribed to the channel (not available for state-change event)
NSNumber *timetoken = event.data.presence.timetoken; // Presence change timetoken
NSString *uuid = event.data.presence.uuid; // UUID of user for which presence change happened
// Only for 'state-change' event
NSDictionary *state = event.data.presence.state; // User state (only for state-change event)
// Only for 'interval' event
NSArray<NSString *> *join = event.data.presence.join; // UUID of users which recently joined channel
NSArray<NSString *> *leave = event.data.presence.leave; // UUID of users which recently leaved channel
NSArray<NSString *> *timeout = event.data.presence.timeout; // UUID of users which recently timed out on channel
}
- (void)client:(PubNub *)pubnub didReceiveObjectEvent:(PNObjectEventResult *)event {
NSString *channel = event.data.channel; // Channel to which the event belongs
NSString *subscription = event.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSString *event = event.data.event; // Can be: set or delete
NSString *type = event.data.type; // Entity type: channel, uuid or membership
NSNumber *timestamp = event.data.timestamp; // Event timestamp
PNChannelMetadata *channelMetadata = event.data.channelMetadata; // Updated channel metadata (only for channel entity type)
PNUUIDMetadata *uuidMetadata = event.data.uuidMetadata; // Updated channel metadata (only for uuid entity type)
PNMembership *membership = event.data.membership; // Updated channel metadata (only for membership entity type)
}
- (void)client:(PubNub *)pubnub didReceiveFileEvent:(PNFileEventResult *)event {
NSString *channel = event.data.channel; // Channel to which file has been uploaded
NSString *subscription = event.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
id message = event.data.message; // Message added for uploaded file
NSString *publisher = event.data.publisher; // UUID of file uploader
NSURL *fileDownloadURL = event.data.file.downloadURL; // URL which can be used to download file
NSString *fileIdentifier = event.data.file.identifier; // Unique file identifier
NSString *fileName = event.data.file.name; // Name with which file has been stored remotely
}
- (void)client:(PubNub *)pubnub didReceiveStatus:(PNStatus *)status {
PNStatusCategory category = status.category; // One of PNStatusCategory fields to identify status of operation processing
PNOperationType operation = status.operation; // One of PNOperationType fields to identify for which operation status received
BOOL isError = status.isError; // Whether any kind of error happened.
NSInteger statusCode = status.statusCode; // Related request processing status code
BOOL isTLSEnabled = status.isTLSEnabled; // Whether secured connection enabled
NSString *uuid = status.uuid; // UUID which configured for passed client
NSString *authKey = status.authKey; // Auth key configured for passed client
NSString *origin = status.origin; // Origin against which request has been sent
NSURLRequest *clientRequest = status.clientRequest; // Request which has been used to send last request (may be nil)
BOOL willAutomaticallyRetry = status.willAutomaticallyRetry; // Whether client will try to perform automatic retry
// Following is available when operation == PNSubscribeOperation,
// because status is PNSubscribeStatus instance in this case
PNSubscribeStatus *subscribeStatus = (PNSubscribeStatus *)status;
NSNumber *currentTimetoken = subscribeStatus.currentTimetoken; // Timetoken which has been used for current subscribe request
NSNumber *lastTimeToken = subscribeStatus.lastTimeToken; // Timetoken which has been used for previous subscribe request
NSArray<NSString *> *subscribedChannels = subscribeStatus.subscribedChannels; // List of channels on which client currently subscribed
NSArray<NSString *> *subscribedChannelGroups = subscribeStatus.subscribedChannelGroups; // List of channel groups on which client currently subscribed
NSString *channel = subscribeStatus.data.channel; // Name of channel to which status has been received
NSString *subscription = subscribeStatus.data.subscription; // Wild-card channel or channel on which PubNub client actually subscribed
NSNumber *timetoken = subscribeStatus.data.timetoken; // Timetoken at which event arrived
NSDictionary *userMetadata = subscribeStatus.data.userMetadata; // Metadata / envelope which has been passed along with event
// Following is available when isError == YES,
// because status is PNErrorStatus instance in this case
PNErrorStatus *errorStatus = (PNErrorStatus *)status;
id associatedObject = errorStatus.associatedObject; // Data which may contain related information (not decrypted message for example)
NSArray<NSString *> *erroredChannels = errorStatus.errorData.channels; // List of channels for which error reported (mostly because of PAM)
NSArray<NSString *> *erroredChannelGroups = errorStatus.errorData.channelGroups; // List of channel groups for which error reported (mostly because of PAM)
NSString *errorInformation = errorStatus.errorData.information; // Stringified information about error
id errorData = errorStatus.errorData.data; // Additional error information from PubNub service
}
// SubscribeCallback is an Abstract Java class. It requires that you
// implement all Abstract methods of the parent class even if you don't
// need all the handler methods.
pubnub.addListener(new SubscribeCallback() {
// PubNub status
@Override
public void status(PubNub pubnub, PNStatus status) {
switch (status.getOperation()) {
// combine unsubscribe and subscribe handling for ease of use
case PNSubscribeOperation:
case PNUnsubscribeOperation:
// Note: subscribe statuses never have traditional errors,
// just categories to represent different issues or successes
// that occur as part of subscribe
switch (status.getCategory()) {
case PNConnectedCategory:
// No error or issue whatsoever.
case PNReconnectedCategory:
// Subscribe temporarily failed but reconnected.
// There is no longer any issue.
case PNDisconnectedCategory:
// No error in unsubscribing from everything.
case PNUnexpectedDisconnectCategory:
// Usually an issue with the internet connection.
// This is an error: handle appropriately.
case PNAccessDeniedCategory:
// PAM does not allow this client to subscribe to this
// channel and channel group configuration. This is
// another explicit error.
default:
// You can directly specify more errors by creating
// explicit cases for other error categories of
// `PNStatusCategory` such as `PNTimeoutCategory` or
// `PNMalformedFilterExpressionCategory` or
// `PNDecryptionErrorCategory`.
}
case PNHeartbeatOperation:
// Heartbeat operations can in fact have errors,
// so it's important to check first for an error.
// For more information on how to configure heartbeat notifications
// through the status PNObjectEventListener callback, refer to
// /docs/sdks/java/android/api-reference/configuration#configuration_basic_usage
if (status.isError()) {
// There was an error with the heartbeat operation, handle here
} else {
// heartbeat operation was successful
}
default: {
// Encountered unknown status type
}
}
}
// Messages
@Override
public void message(PubNub pubnub, PNMessageResult message) {
String messagePublisher = message.getPublisher();
System.out.println("Message publisher: " + messagePublisher);
System.out.println("Message Payload: " + message.getMessage());
System.out.println("Message Subscription: " + message.getSubscription());
System.out.println("Message Channel: " + message.getChannel());
System.out.println("Message timetoken: " + message.getTimetoken());
}
// Presence
@Override
public void presence(@NotNull PubNub pubnub, @NotNull PNPresenceEventResult presence) {
System.out.println("Presence Event: " + presence.getEvent());
// Can be join, leave, state-change or timeout
System.out.println("Presence Channel: " + presence.getChannel());
// The channel to which the message was published
System.out.println("Presence Occupancy: " + presence.getOccupancy());
// Number of users subscribed to the channel
System.out.println("Presence State: " + presence.getState());
// User state
System.out.println("Presence UUID: " + presence.getUuid());
// UUID to which this event is related
presence.getJoin();
// List of users that have joined the channel (if event is 'interval')
presence.getLeave();
// List of users that have left the channel (if event is 'interval')
presence.getTimeout();
// List of users that have timed-out off the channel (if event is 'interval')
presence.getHereNowRefresh();
// Indicates to the client that it should call 'hereNow()' to get the
// complete list of users present in the channel.
}
// Signals
@Override
public void signal(PubNub pubnub, PNSignalResult pnSignalResult) {
System.out.println("Signal publisher: " + signal.getPublisher());
System.out.println("Signal payload: " + signal.getMessage());
System.out.println("Signal subscription: " + signal.getSubscription());
System.out.println("Signal channel: " + signal.getChannel());
System.out.println("Signal timetoken: " + signal.getTimetoken());
}
// Message actions
@Override
public void messageAction(PubNub pubnub, PNMessageActionResult pnActionResult) {
PNMessageAction pnMessageAction = pnActionResult.getAction();
System.out.println("Message action type: " + pnMessageAction.getType());
System.out.println("Message action value: " + pnMessageAction.getValue());
System.out.println("Message action uuid: " + pnMessageAction.getUuid());
System.out.println("Message action actionTimetoken: " + pnMessageAction.getActionTimetoken());
System.out.println("Message action messageTimetoken: " + pnMessageAction.getMessageTimetoken());]
System.out.println("Message action subscription: " + pnActionResult.getSubscription());
System.out.println("Message action channel: " + pnActionResult.getChannel());
System.out.println("Message action timetoken: " + pnActionResult.getTimetoken());
}
// Files
@Override
public void file(PubNub pubnub, PNFileEventResult pnFileEventResult) {
System.out.println("File channel: " + pnFileEventResult.getChannel());
System.out.println("File publisher: " + pnFileEventResult.getPublisher());
System.out.println("File message: " + pnFileEventResult.getMessage());
System.out.println("File timetoken: " + pnFileEventResult.getTimetoken());
System.out.println("File file.id: " + pnFileEventResult.getFile().getId());
System.out.println("File file.name: " + pnFileEventResult.getFile().getName());
System.out.println("File file.url: " + pnFileEventResult.getFile().getUrl());
}
});
pubnub.AddListener(new SubscribeCallbackExt(
// Messages
delegate (Pubnub pnObj, PNMessageResult<object> pubMsg)
{
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(pubMsg));
var channelName = pubMsg.Channel;
var channelGroupName = pubMsg.Subscription;
var pubTT = pubMsg.Timetoken;
var msg = pubMsg.Message;
var publisher = pubMsg.Publisher;
},
// Presence
delegate (Pubnub pnObj, PNPresenceEventResult presenceEvnt)
{
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(presenceEvnt));
var action = presenceEvnt.Event; // Can be join, leave, state-change or timeout
var channelName = presenceEvnt.Channel; // The channel to which the message belongs
var occupancy = presenceEvnt.Occupancy; // Number of users connected with the channel
var state = presenceEvnt.State; // User State
var channelGroupName = presenceEvnt.Subscription; // The channel group or wildcard subscription match (if exists)
var publishTime = presenceEvnt.Timestamp; // Publish timetoken
var timetoken = presenceEvnt.Timetoken; // Current timetoken
var uuid = presenceEvnt.Uuid; // UUIDs of users who are connected with the channel
},
// Signals
delegate (Pubnub pnObj, PNSignalResult<object> signalMsg)
{
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(signalMsg));
var channelName = signalMsg.Channel; // The channel to which the signal belongs
var channelGroupName = signalMsg.Subscription; // The channel group or wildcard subscription match (if exists)
var pubTT = signalMsg.Timetoken; // Publish timetoken
var msg = signalMsg.Message; // The Payload
var publisher = signalMsg.Publisher; //The Publisher
},
// Objects
delegate (Pubnub pnObj, PNObjectEventResult objectEventObj)
{
var channelName = objectEventObj.Channel; // Channel
var channelMetadata = objectEventObj.ChannelMetadata; //Channel Metadata
var uidMetadata = objectEventObj.UuidMetadata; // UUID metadata
var evnt = objectEventObj.Event; // Event
var type = objectEventObj.Type; // Event type
if (objectEventObj.Type == "uuid") { /* got uuid metadata related event */ }
else if (objectEventObj.Type == "channel") { /* got channel metadata related event */ }
else if (objectEventObj.Type == "membership") { /* got membership related event */ }
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(objectEventObj));
},
// Message actions
delegate (Pubnub pnObj, PNMessageActionEventResult msgActionEvent)
{
var channelName = msgActionEvent.Channel; // The channel to which the message belongs
var msgEvent = msgActionEvent.Action; // Message action added or removed
var msgActionType = msgActionEvent.Event; // Message action type
var messageTimetoken = msgActionEvent.MessageTimetoken; // The timetoken of the original message
var actionTimetoken = msgActionEvent.ActionTimetoken; // The timetoken of the message action
},
// Files
delegate (Pubnub pnObj, PNFileEventResult fileEvent)
{
// Handle file message event
var channelName = fileEvent.Channel;
var chanelGroupName = fileEvent.Subscription;
var fieldId = (fileEvent.File != null) ? fileEvent.File.Id : null;
var fileName = (fileEvent.File != null) ? fileEvent.File.Name : null;
var fileUrl = (fileEvent.File != null) ? fileEvent.File.Url : null;
var fileMessage = fileEvent.Message;
var filePublisher = fileEvent.Publisher;
var filePubTT = fileEvent.Timetoken;
},
// Status
delegate (Pubnub pnObj, PNStatus pnStatus)
{
Console.WriteLine("{0} {1} {2}", pnStatus.Operation, pnStatus.Category, pnStatus.StatusCode);
var affectedChannelGroups = pnStatus.AffectedChannelGroups; // The channel groups affected in the operation, of type array
var affectedChannels = pnStatus.AffectedChannels; // The channels affected in the operation, of type array
var category = pnStatus.Category; // Returns PNConnectedCategory
var operation = pnStatus.Operation; // Returns PNSubscribeOperation
}
));
import (
pubnub "github.com/pubnub/go"
)
listener := pubnub.NewListener()
go func() {
for {
select {
case signal := <-listener.Signal:
// Channel
fmt.Println(signal.Channel)
// Subscription
fmt.Println(signal.Subscription)
// Payload
fmt.Println(signal.Message)
// Publisher ID
fmt.Println(signal.Publisher)
// Timetoken
fmt.Println(signal.Timetoken)
case status := <-listener.Status:
switch status.Category {
case pubnub.PNDisconnectedCategory:
// This is the expected category for an unsubscribe. This means there
// was no error in unsubscribing from everything.
case pubnub.PNConnectedCategory:
// This is expected for a subscribe. This means
// there is no error or issue whatsoever.
case pubnub.PNReconnectedCategory:
// This usually occurs if subscribe temporarily fails but reconnects.
// This means there was an error but there is no longer any issue.
case pubnub.PNAccessDeniedCategory:
// This means that PAM doesn't allow this client to subscribe to this
// channel and channel group configuration. This is another explicit error.
}
case message := <-listener.Message:
// Channel
fmt.Println(message.Channel)
// Subscription
fmt.Println(message.Subscription)
// Payload
fmt.Println(message.Message)
// Publisher ID
fmt.Println(message.Publisher)
// Timetoken
fmt.Println(message.Timetoken)
case presence := <-listener.Presence:
fmt.Println(presence.Event)
// Channel
fmt.Println(presence.Channel)
// Subscription
fmt.Println(presence.Subscription)
// Timetoken
fmt.Println(presence.Timetoken)
// Occupancy
fmt.Println(presence.Occupancy)
case uuidEvent := <-listener.UUIDEvent:
fmt.Println(fmt.Sprintf("uuidEvent.Channel: %s", uuidEvent.Channel))
fmt.Println(fmt.Sprintf("uuidEvent.SubscribedChannel: %s", uuidEvent.SubscribedChannel))
fmt.Println(fmt.Sprintf("uuidEvent.Event: %s", uuidEvent.Event))
fmt.Println(fmt.Sprintf("uuidEvent.UUID: %s", uuidEvent.UUID))
fmt.Println(fmt.Sprintf("uuidEvent.Description: %s", uuidEvent.Description))
fmt.Println(fmt.Sprintf("uuidEvent.Timestamp: %s", uuidEvent.Timestamp))
fmt.Println(fmt.Sprintf("uuidEvent.Name: %s", uuidEvent.Name))
fmt.Println(fmt.Sprintf("uuidEvent.ExternalID: %s", uuidEvent.ExternalID))
fmt.Println(fmt.Sprintf("uuidEvent.ProfileURL: %s", uuidEvent.ProfileURL))
fmt.Println(fmt.Sprintf("uuidEvent.Email: %s", uuidEvent.Email))
fmt.Println(fmt.Sprintf("uuidEvent.Updated: %s", uuidEvent.Updated))
fmt.Println(fmt.Sprintf("uuidEvent.ETag: %s", uuidEvent.ETag))
fmt.Println(fmt.Sprintf("uuidEvent.Custom: %v", uuidEvent.Custom))
case channelEvent := <-listener.ChannelEvent:
fmt.Println(fmt.Sprintf("channelEvent.Channel: %s", channelEvent.Channel))
fmt.Println(fmt.Sprintf("channelEvent.SubscribedChannel: %s", channelEvent.SubscribedChannel))
fmt.Println(fmt.Sprintf("channelEvent.Event: %s", channelEvent.Event))
fmt.Println(fmt.Sprintf("channelEvent.Channel: %s", channelEvent.Channel))
fmt.Println(fmt.Sprintf("channelEvent.Description: %s", channelEvent.Description))
fmt.Println(fmt.Sprintf("channelEvent.Timestamp: %s", channelEvent.Timestamp))
fmt.Println(fmt.Sprintf("channelEvent.Updated: %s", channelEvent.Updated))
fmt.Println(fmt.Sprintf("channelEvent.ETag: %s", channelEvent.ETag))
fmt.Println(fmt.Sprintf("channelEvent.Custom: %v", channelEvent.Custom))
case membershipEvent := <-listener.MembershipEvent:
fmt.Println(fmt.Sprintf("membershipEvent.Channel: %s", membershipEvent.Channel))
fmt.Println(fmt.Sprintf("membershipEvent.SubscribedChannel: %s", membershipEvent.SubscribedChannel))
fmt.Println(fmt.Sprintf("membershipEvent.Event: %s", membershipEvent.Event))
fmt.Println(fmt.Sprintf("membershipEvent.Channel: %s", membershipEvent.Channel))
fmt.Println(fmt.Sprintf("membershipEvent.UUID: %s", membershipEvent.UUID))
fmt.Println(fmt.Sprintf("membershipEvent.Description: %s", membershipEvent.Description))
fmt.Println(fmt.Sprintf("membershipEvent.Timestamp: %s", membershipEvent.Timestamp))
fmt.Println(fmt.Sprintf("membershipEvent.Custom: %v", membershipEvent.Custom))
case messageActionsEvent := <-listener.MessageActionsEvent:
fmt.Println(fmt.Sprintf("messageActionsEvent.Channel: %s", messageActionsEvent.Channel))
fmt.Println(fmt.Sprintf("messageActionsEvent.SubscribedChannel: %s", messageActionsEvent.SubscribedChannel))
fmt.Println(fmt.Sprintf("messageActionsEvent.Event: %s", messageActionsEvent.Event))
fmt.Println(fmt.Sprintf("messageActionsEvent.Data.ActionType: %s", messageActionsEvent.Data.ActionType))
fmt.Println(fmt.Sprintf("messageActionsEvent.Data.ActionValue: %s", messageActionsEvent.Data.ActionValue))
fmt.Println(fmt.Sprintf("messageActionsEvent.Data.ActionTimetoken: %s", messageActionsEvent.Data.ActionTimetoken))
fmt.Println(fmt.Sprintf("messageActionsEvent.Data.MessageTimetoken: %s", messageActionsEvent.Data.MessageTimetoken))
case file := <-listener.File:
fmt.Println(fmt.Sprintf("file.File.PNMessage.Text: %s", file.File.PNMessage.Text))
fmt.Println(fmt.Sprintf("file.File.PNFile.Name: %s", file.File.PNFile.Name))
fmt.Println(fmt.Sprintf("file.File.PNFile.ID: %s", file.File.PNFile.ID))
fmt.Println(fmt.Sprintf("file.File.PNFile.URL: %s", file.File.PNFile.URL))
fmt.Println(fmt.Sprintf("file.Channel: %s", file.Channel))
fmt.Println(fmt.Sprintf("file.Timetoken: %d", file.Timetoken))
fmt.Println(fmt.Sprintf("file.SubscribedChannel: %s", file.SubscribedChannel))
fmt.Println(fmt.Sprintf("file.Publisher: %s", file.Publisher))
}
}
}
# The Python SDK doesn't currently support *Server Objects*,
# so it doesn't have any handlers for them.
class SubscribeHandler(SubscribeCallback):
def status(self, pubnub, event):
print("Is there an error? ", event.is_error()) # Method showing error or not
print("Status value for category: %s" % event.category)
print("Status value for error_data: %s" % event.error_data)
print("Status value for error: %s" % event.error)
print("Status value for status_code: %s" % event.status_code)
print("Status value for operation: %s" % event.operation)
print("Status value for tls_enabled: %s" % event.tls_enabled)
print("Status value for uuid: %s" % event.uuid)
print("Status value for auth_key: %s" % event.auth_key)
print("Status value for origin: %s" % event.origin)
print("Status value for client_request: %s" % event.client_request)
print("Status value for client_response: %s" % event.client_response)
print("Status value for original_response: %s" % event.original_response)
print("Status value for affected_channels: %s" % event.affected_channels)
print("Status value for affected_groups: %s" % event.affected_groups)
def presence(self, pubnub, presence):
pass # Handle incoming presence data
def message(self, pubnub, message):
pass # Handle incoming messages
def signal(self, pubnub, signal):
pass # Handle incoming signals
def file(self, pubnub, file_message):
pass # Handle incoming files
pubnub.add_listener(SubscribeHandler())
The following is an overview of each of the listener's event handlers. Details about the data passed to the handlers' parameters will be explained in the API sections of the associated handlers.
Handler | Description |
---|---|
Status | Receives events when the client successfully connects (subscribes), or reconnects (in case of connection issues) to channels. There are other error events that can be received by the Status handler; refer to Connection Management and to the tip that follows this table. |
Message | Receives all messages published to all the channels subscribed by the client. The event payload will contain the published message data, publish timetoken, the UUID of the client that published the message and more. Refer to Publish Messages. |
Signal | Receives all signals that are sent to any channels subscribed by the client. The event payload will contain the signal data, signal timetoken, the UUID of the client that published the message and more. Refer to Send Signals. |
Presence | Receives all presence events that are triggered on any channels subscribed by the client. The event payload will contain the presence event type (join , leave , timeout , state-change ), timetoken of the action, the UUID of the client that caused the event, state data (if applicable) and more. Refer to Detect Presence. |
MessageAction | Receives all events when existing messages are annotated (by an action) for any channels subscribed by the client. The event payload will contain the UUID that acted on the message, message action type (such as an emoji reaction), timetoken of the annotated message, timetoken of the action, action value and more. Refer to Message Actions. |
Objects | Receives all objects events that are emitted when a channel, channel membership, or user metadata is created, updated or removed. Refer to Channel Metadata and User Metadata. |
Status event handling
For more information on how the SDKs handle status events, refer to SDK troubleshooting and status event references.
Architectural Decisions
For a straightforward use case, go through the architecture decisions page. For advanced use cases where you may want to aggregate messages on the server, refer to the server message aggregation guide. And, for building a social app, please go through building friend lists and status feeds.
Next Steps
Now that you have your account and listeners set up, go publish some messages!