Feedback

C#C# V4 API Reference for Realtime Apps

C# V4 complete API reference for building Realtime Applications on PubNub, including basic usage and sample code.
PNConfiguration instance is storage for user-provided information which describe further PubNub client behaviour. Configuration instance contain additional set of properties which allow to perform precise PubNub client configuration.
To create configuration instance you can use the following function in the C# V4 SDK:
  1. PropertiesTypeRequiredDescription
    SubscribeKeystringYesSubscribeKey from admin panel.
    PublishKeystringOptionalPublishKey from admin panel (only required if publishing).
    SecretKeystringOptionalSecretKey (only required for access operations, keep away from Android).
    CipherKeystringOptionalIf cipher is passed, all communicatons to/from PubNub will be encrypted.
    UuidstringOptionalUuid to be used as a device identifier, a default Uuid is generated if not passed.
    LogVerbosityPNLogVerbosityOptionalSet PNLogVerbosity.BODY to enable debugging. To disable debugging use the option PNLogVerbosity.NONE
    AuthKeystringOptionalIf Access Manager is utilized, client will use this AuthKey in all restricted requests.
    SecureboolOptionalUse SSL.
    SubscribeTimeoutintOptionalHow long to keep the subscribe loop running before disconnect.
    NonSubscribeRequestTimeoutintOptionalOn non subscribe operations, how long to wait for server response.
    FilterExpressionstringOptionalFeature to subscribe with a custom filter expression.
    HeartbeatNotificationOptionPNHeartbeatNotificationOptionOptional

    Heartbeat notifications, by default, the SDK will alert on failed heartbeats (equivalent to: PNHeartbeatNotificationOption.FAILURES).

    Other options such as all heartbeats (PNHeartbeatNotificationOption.ALL) or no heartbeats (PNHeartbeatNotificationOption.NONE) are supported.

    OriginstringOptionalCustom Origin if needed.
    ReconnectionPolicyPNReconnectionPolicyOptional

    Set to PNReconnectionPolicy.LINEAR for automatic reconnects. Use option PNReconnectionPolicy.NONE to disable automatic reconnects.

    Use option PNReconnectionPolicy.EXPONENTIAL to set exponential retry interval.

    PresenceTimeoutintOptionalThe setting with set the custom presence server timeout.
    PresenceIntervalintOptionalThe setting with set the custom presence server timeout along with the custom interval to send the ping back to the server.
    ProxyProxyOptionalInstruct the SDK to use a Proxy configuration when communicating with PubNub servers.
    PubnubLogIPubnubLogOptionalPass the instance of a class that implements IPubnubLog to capture logs for troubleshooting.
    UseClassicHttpWebRequestboolOptionalUse HttpWebRequest to support ASP.NET/MVC and other IIS hosting applications.
PNConfiguration pnConfiguration = new PNConfiguration();
// subscribeKey from admin panel
pnConfiguration.SubscribeKey = "SubscribeKey"; // required
// publishKey from admin panel (only required if publishing)
pnConfiguration.PublishKey = "PublishKey";
// secretKey (only required for access operations)
pnConfiguration.SecretKey = "SecretKey";
// if cipherKey is passed, all communicatons to/from pubnub will be encrypted
pnConfiguration.CipherKey = "cipherKey";
// Uuid to be used as a device identifier, a default Uuid is generated 
// if not passed
pnConfiguration.Uuid = "customUUID";
// Enable Debugging
pnConfigurationr.LogVebosity = PNLogVerbosity.BODY;
// if Access Manager is utilized, client will use this AuthKey in all restricted
// requests
pnConfiguration.AuthKey = "authKey";
// use SSL.
pnConfiguration.Secure = true;
// how long to keep the subscribe loop running before disconnect
pnConfiguration.SubscribeTimeout = 310;
// on non subscribe operations, how long to wait for server response
pnConfiguration.NonSubscribeRequestTimeout = 300;
// PSV2 feature to subscribe with a custom filter expression
pnConfiguration.FilterExpression = "such=wow";
// heartbeat notifications, by default, the SDK will alert on failed heartbeats.
// other options such as all heartbeats or no heartbeats are supported.
pnConfiguration.HeartbeatNotificationOption = PNHeartbeatNotificationOption.All;
pnConfiguration.SetPresenceTimeoutWithCustomInterval(120, 59);
pnConfiguration.PresenceTimeout = 120;
// Use HttpWebRequest to support ASP.NET/MVC and other IIS hosting applications
pnConfiguration.UseClassicHttpWebRequest= true;
using PubnubApi;
This function is used for initializing the PubNub Client API context. This function must be called before attempting to utilize any API functionality in order to establish account level credentials such as PublishKey and SubscribeKey.
To Initialize Pubnub you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    pnConfigurationPNConfigurationYesGoto Configuration for more details.
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.PublishKey = "my_pubkey";
pnConfiguration.SubscribeKey = "my_subkey";
pnConfiguration.Secure = true;

Pubnub pubnub = new Pubnub(pnConfiguration);
It returns the Pubnub instance for invoking PubNub APIs like Publish(), Subscribe(), History(), HereNow(), etc.
  1. PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.PublishKey = "my_pubkey";
    pnConfiguration.SubscribeKey = "my_subkey";
    pnConfiguration.Secure = false;
    
    Pubnub pubnub = new Pubnub(pnConfiguration);
  2. In the case where a client will only read messages and never publish to a channel, you can simply omit the PublishKey when initializing the client:
    PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.SubscribeKey = "my_subkey";
    Pubnub pubnub = new Pubnub(pnConfiguration);
  3. Under certain circumstances it useful to use a custom UUID to help in identifying your users.
    PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.PublishKey = "my_pubkey";
    pnConfiguration.SubscribeKey = "my_subkey";
    pnConfiguration.Uuid = "Stephen";
    
    Pubnub pubnub = new Pubnub(pnConfiguration);
  4. This examples demonstrates how to enable PubNub Transport Layer Encryption with SSL. Just initialize the client with ssl set to true. The hard work is done, now the PubNub API takes care of the rest. Just subscribe and publish as usual and you are good to go.
    PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.PublishKey = "my_pubkey";
    pnConfiguration.SubscribeKey = "my_subkey";
    pnConfiguration.Secure = true;
    
    Pubnub pubnub = new Pubnub(pnConfiguration);
  5.  
    Anyone with the SecretKey can grant and revoke permissions to your app. Never let your SecretKey be discovered, and to only exchange it / deliver it securely. Only use the SecretKey on secure server-side platforms.
    For applications that will administer PAM permissions, the API is initialized with the SecretKey as in the following example:
    PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.PublishKey = "my_pubkey";
    pnConfiguration.SubscribeKey = "my_subkey";
    pnConfiguration.SecretKey = "my_secretkey";
    pnConfiguration.Secure = true;
    
    Pubnub pubnub = new Pubnub(pnConfiguration);
    Now that the pubnub object is instantiated the client will be able to access the PAM functions. The pubnub object will use the SecretKey to sign all PAM messages to the PubNub Network.
These functions are used to set/get a user ID on the fly.
To set/get UUID you can use the following property(s) in C# V4 SDK
  1. PropertyTypeRequiredDescription
    UuidstringYesUuid to be used as a device identifier, a default Uuid is generated if not passed.
  2. This method doesn't take any arguments.
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.Uuid = "customUUID";
var customUUID = pnConfiguration.Uuid;
Setter and getter for users auth key.
  1. PropertyTypeRequiredDescription
    AuthKeystringYesIf Access Manager is utilized, client will use this AuthKey in all restricted requests.
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.AuthKey = "authKey";
var sampleAuthKey = pnConfiguration.AuthKey;
Get Auth key returns the current authentication key.
To set/get filters you can use the following methods.
  1. PropertyTypeRequiredDescription
    FilterExpressionstringYesPSV2 feature to Subscribe with a custom filter expression.
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.FilterExpression = "such=wow";
var sampleFilterExp = pnConfiguration.FilterExpression;
The Publish() function is used to send a message to all subscribers of a channel. To publish a message you must first specify a valid PublishKey at initialization. A successfully published message is replicated across the PubNub Real-Time Network and sent simultaneously to all subscribed clients on a channel.
Messages in transit can be secured from potential eavesdroppers with SSL/TLS by setting ssl to true during initialization.
 
Publish Anytime
It is not required to be subscribed to a channel in order to publish to that channel.
Message Data:
The message argument can contain any JSON serializable data, including: Objects, Arrays, Ints and Strings. Message data should not contain special C# V4 classes or functions as these will not serialize. String content can include any single-byte or multi-byte UTF-8 character.
Message Size:
The maximum number of characters per message is 32K by default. The maximum message size is based on the final escaped character count, including the channel name. An ideal message size is under 1800 bytes which allows a message to be compressed and sent using single IP datagram (1.5KB) providing optimal network performance.
If the message you publish exceeds the configured size, you will receive the following message:
Message Too Large Error
["PUBLISHED",[0,"Message Too Large","13524237335750949"]]
Message Publish Rate:
Messages can be published as fast as bandwidth conditions will allow. There is a soft limit based on max throughput since messages will be discarded if the subscriber cannot keep pace with the publisher.
For example, if 200 messages are published simultaneously before a subscriber has had a chance to receive any messages, the subscriber may not receive the first 100 messages because the message queue has a limit of only 100 messages stored in memory.
Publishing to Multiple Channels.
It is not possible to publish a message to multiple channels simultaneously. The message must be published to one channel at a time.
Publishing Messages Reliably.
There are some best practices to ensure messages are delivered when publishing to a channel:
  • Publish to any given channel in a serial manner (i.e. not concurrently).
  • Check that the return code is success (e.g. [1,"Sent","136074940..."])
  • Publish the next message only after receiving a success return code.
  • If a failure code is returned ([0,"blah","<timetoken>"]), retry the publish.
  • Avoid exceeding the in-memory queue's capacity of 100 messages. An overflow situation (aka missed messages) can occur if slow subscribers fail to keep up with the publish pace in a given period of time.
  • Throttle publish bursts in accordance with your app's latency needs e.g. Publish no faster than 5 msgs per second to any one channel.
 
Do Not JSON serialize!
It is important to note that you should not JSON serialize when sending signals/messages via PUBNUB. Why? Because the serialization is done for you automatically. Instead just pass the full object as the message payload. PubNub takes care of everything for you.
 

Single string messages are automatically sent to APNS if mobile push is enabled and devices are registered for push on that channel. So if you use encryption (cipher key in the init) and publish the message, then it will be sent to APNS if there is a device(s) registered to that channel.

This is a legacy feature and will be deprecated soon.

To Publish a message you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    MessageobjectYesThe payload.
    ChannelstringYesDestination of the Message.
    ShouldStoreboolOptional

    Store in history.

    If ShouldStore is not specified, then the history configuration on the key is used.

    MetaDictionary<string, object>OptionalMeta data object which can be used with the filtering ability.
    UsePOSTboolOptionalUse POST to Publish.
    TtlintOptional
    Set a per message time to live in storage.
    1. If ShouldStore = true, and Ttl = 0, the message stored with no expiry time.
    2. If ShouldStore = true and Ttl = X (X is an Integer value), the message is stored with an expiry time of X hours.
    3. If ShouldStore = false, the Ttl parameter is ignored.
    4. If Ttl is not specified, then expiration of the message defaults back to the expiry value for the key.
    SyncCommandOptionalBlock the thread, exception thrown if something goes wrong.
    AsyncPNCallbackOptionalPNCallback of type PNPublishResult.

Publish a message to a channel:

string[] arrayMessage = new string[] { 
    "hello", 
    "there"
};
 
pubnub.Publish()
    .Message(arrayMessage.ToList())
    .Channel("my_channel")
    .ShouldStore(true)
    .UsePOST(true)
    .Async(new PNPublishResultExt(
        (result, status) => {
            // Check whether request successfully completed or not.
            if (status.Error) {
                // something bad happened.
                Console.WriteLine("error happened while publishing: " + pubnub.JsonPluggableLibrary.SerializeToJsonString(status));
            } else {
                Console.WriteLine("publish worked! timetoken: " + result.Timetoken.ToString());
            }
        }
    ));
 
Before running the above publish example, either using the Debug Console, or in a separate script running in a separate terminal window, subscribe to the same channel that is being published to.
The Publish() operation returns a PNPublishResult which contains the following parameter:
Property NameTypeDescription
TimetokenlongReturns a long representation of the time token when the message was published.
  1. string[] arrayMessage = new string[] { 
        "hello",
        "there"
    };
     
    pubnub.Publish()
        .Message(arrayMessage.ToList())
        .Channel("suchChannel")
        .ShouldStore(true)
        .Meta("<json data as dictionary object>")
        .UsePOST(true)
        .Async(new PNPublishResultExt(
            (result, status) => {
                // handle publish result, status always present, result if successful
                // status.Error to see if error happened
            }
        ));
  2. //Publishing Dictionary
    Dictionary<string, float> position = new Dictionary<string, float>();
    position.Add("lat", 32F);
    position.Add("lng", 32F);
     
    Console.WriteLine("before pub: " + pubnub.JsonPluggableLibrary.SerializeToJsonString(position));
     
    pubnub.Publish()
        .Message(position)
        .Channel("my_channel")
        .Async(new PNPublishResultExt(
            (result, status) => {
                Console.WriteLine("pub timetoken: " + result.Timetoken.ToString());
                Console.WriteLine("pub status code : " + status.StatusCode.ToString());
            }
        ));
  3. PNPublishResult res = pubnub.Publish()
        .Channel("coolChannel")
        .Message("test")
        .ShouldStore(true)
        .Ttl(10)
        .Sync();
The fire endpoint allows the client to send a message to BLOCKS Event Handlers. These messages will go directly to any Event Handlers registered on the channel that you fire to and will trigger their execution. The content of the fired request will be available for processing within the Event Handler. The message sent via fire() is not replicated, and so will not be received by any subscribers to the channel. The message is also not stored in history.
To Fire a message you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    MessageobjectYesThe payload.
    ChannelstringYesDestination of the message.
    MetaDictionary<string, object>OptionalMeta data object which can be used with the filtering ability.
    UsePOST
    boolOptionalUse POST to Publish.
    SyncCommandOptionalBlock the thread, exception thrown if something goes wrong.
    AsyncPNCallbackOptionalPNCallback of type PNPublishResult

Fire a message to a channel:

string[] arrMessage = new string[] { 
    "hello",
    "there"
};
 
pubnub.Fire()
    .Message(arrMessage.ToList())
    .Channel(channel)
    .UsePOST(true)
    .Async(new PNPublishResultExt(
        (result, status) => {
            if (status.Error) {
            	// something bad happened.
            	Console.WriteLine("error happened while publishing: " + pubnub.JsonPluggableLibrary.SerializeToJsonString(status));
            } else {
            	Console.WriteLine("publish worked! timetoken: " + result.Timetoken.ToString());
            }
        }
    ));
This function causes the client to create an open TCP socket to the PubNub Real-Time Network and begin listening for messages on a specified channel. To subscribe to a channel the client must send the appropriate SubscribeKey at initialization.
By default a newly subscribed client will only receive messages published to the channel after the Subscribe() call completes.
If a client gets disconnected from a channel, it can automatically attempt to reconnect to that channel and retrieve any available messages that were missed during that period. This can be achieved by setting ReconnectionPolicy to PNReconnectionPolicy.LINEAR, when initializing the client.
To Subscribe to a channel you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalSubscribe to Channels, Either Channels or ChannelGroups is required.
    ChannelGroupsArrayOptionalSubscribe to ChannelGroups, Either Channels or ChannelGroups is required.
    WithTimetokenlongOptionalPass a Timetoken.
    WithPresenceCommandOptionalAlso subscribe to related presence information.
    ExecuteCommandYesCommand that will Execute Subscribe.
Subscribe to a channel:
pubnub.Subscribe<string>()
    .Channels(new string[] {
        // subscribe to channels
        "my_channel" 
     })
    .Execute();
The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.
 

PNMessageResult<T> is returned in the Listeners.

The Subscribe() operation returns a PNMessageResult<T> for messages which contains the following operations:
Property NameTypeDescription
MessageobjectThe message sent on the channel.
SubscriptionstringThe channel group or wildcard subscription match (if exists).
ChannelstringThe channel for which the message belongs.
TimetokenlongTimetoken for the message.
UserMetadataobjectUser metadata.
The Subscribe() operation returns a PNPresenceEventResult from presence which contains the following operations:
Property NameTypeDescription
EventstringEvents like join, leave, timeout, state-change, interval.
UuidstringUUID for the event.
TimestamplongTimestamp for the event.
OccupancyintCurrent occupancy.
StateDictionaryState of the UUID.
SubscriptionstringThe channel group or wildcard subscription match (if exists).
ChannelstringThe channel for which the message belongs.
TimetokenlongTimetoken of the message.
UserMetadataobjectUser metadata.
  1. PNConfiguration pnConfiguration = new PNConfiguration();
    // subscribeKey from admin panel
    pnConfiguration.SubscribeKey = "my_subkey"; // required
    // publishKey from admin panel (only required if publishing)
    pnConfiguration.PublishKey = "my_pubkey";
    // secretKey (only required for access operations)
    pnConfiguration.LogVerbosity = PNLogVerbosity.BODY;
    Pubnub pubnub = new Pubnub(pnConfiguration);
    
    pubnub.Subscribe<string>()
        .Channels(new string[] {
            // subscribe to channels
            "my_channel"
        }) 
        .Execute();
  2. It is possible to subscribe to more than one channel over a single TCP socket by taking advantage of Multiplexing feature. See the Multiplexing section for more info on this feature as well as the examples below using a list or an array to specify channel name.
    pubnub.Subscribe<string>()
        .Channels(new string[] { 
            // subscribe to channels information
            "my_channel1",
            "my_channel2" 
        })
        .Execute();
  3. For any given channel there is an associated Presence channel. You can subscribe directly to the channel by appending -pnpres to the channel name. For example the channel named my_channel would have the presence channel named my_channel-pnpres.
    pubnub.Subscribe<string>()
        .Channels(new string[] {
            // subscribe to channels
            "my_channel" 
        })
        .WithPresence() // also subscribe to related presence information
        .Execute();
    {
    	"action": "join",
    	"timestamp": 1345546797,
    	"uuid": "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
    	"occupancy": 2
    }
    
    {
        "action" : "leave",
        "timestamp" : 1345549797,
        "uuid" : "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
        "occupancy" : 1
    }
    {
    	"action": "timeout",
    	"timestamp": 1345549797,
    	"uuid": "76c2c571-9a2b-d074-b4f8-e93e09f49bd",
    	"occupancy": 0
    }
    
    {
    	"action": "state-change",
    	"uuid": "76c2c571-9a2b-d074-b4f8-e93e09f49bd",
    	"timestamp": 1345549797,
    	"data": {
    		"isTyping": true
    	}
    }
    
    {
    	"action":"interval",
    	"timestamp":1474396578,
    	"occupancy":2
    }
    

    When a channel is in interval mode with presence_deltas pnconfig flag enabled, the interval message may also include the following fields which contain an array of changed UUIDs since the last interval message.

    • joined
    • left
    • timedout

    For example, this interval message indicates there were 2 new UUIDs that joined and 1 timed out UUID since the last interval:

    {
        "action" : "interval",
        "occupancy" : <# users in channel>,
        "timestamp" : <unix timestamp>,
        "joined" : ["uuid2", "uuid3"],
        "timedout" : ["uuid1"]
    }
    

    If the full interval message is greater than 30KB (since the max publish payload is ∼32KB), none of the extra fields will be present. Instead there will be a here_now_refresh boolean field set to true. This indicates to the user that they should do a hereNow request to get the complete list of users present in the channel.

    {
        "action" : "interval",
        "occupancy" : <# users in channel>,
        "timestamp" : <unix timestamp>,
        "here_now_refresh" : true
    }
    
  4. Wildcard subscribes allow the client to subscribe to multiple channels using wildcard. E.g., if you subscribe to a.* you will get all messages for a.b, a.c, a.x. The wildcarded * portion refers to any portion of the channel string name after the dot (.).
    pubnub.Subscribe<string>()
        .Channels(new string[] { 
            // subscribe to channels information
            "foo.*" 
        })
        .Execute();
  5. You can set state for a uuid during a subscribe by using the state parameter. Simply specify the desired key/value pairs as a JSON object.
    PNConfiguration pnConfiguration = new PNConfiguration();
    pnConfiguration.SubscribeKey = "demo";
    pnConfiguration.PublishKey = "demo";
    Pubnub pubnub = new Pubnub(pnConfiguration);
    pubnub.AddListener(new SubscribeCallbackExt(
        (pubnubObj, message) => {  },
        (pubnubObj, presence) => {  },
        (pubnubObj, status) => {
            if (status.Category == PNStatusCategory.PNConnectedCategory) {
                Dictionary<string, object> data = new Dictionary<string, object>();
                data.Add("FieldA", "Awesome");
                data.Add("FieldB", 10);
    
                pubnub.SetPresenceState()
                    .Channels(new string[] { "awesomeChannel" })
                    .ChannelGroups(new string[] { "awesomeChannelGroup" })
                    .State(data)
                    .Async(new PNSetStateResultExt(
                        (r, s) => {
                            // handle set state response
                        }
                    ));
            }
        }
    ));
    
    pubnub.Subscribe<string>()
        .Channels(new string[] {
            "awesomeChannel"
        }) 
        .Execute();
  6. pubnub.Subscribe<string>()
        .Channels(new string[] {
            // subscribe to channels
            "ch1",
            "ch2"
        }) 
        .ChannelGroups(new string[] {
            // subscribe to channel groups
            "cg1",
            "cg2"
        }) 
        .WithTimetoken(1337L) // optional, pass a timetoken
        .WithPresence() // also subscribe to related presence information
        .Execute();
  7. pubnub.Subscribe<string>()
        .ChannelGroups(new string[] {
            // subscribe to channel groups
            "cg1",
            "cg2"
        }) 
        .WithTimetoken(1337L) // optional, pass a timetoken
        .WithPresence() // also subscribe to related presence information
        .Execute();
When subscribed to a single channel, this function causes the client to issue a leave from the channel and close any open socket to the PubNub Network. For multiplexed channels, the specified channel(s) will be removed and the socket remains open until there are no more channels remaining in the list.
To Unsubscribe from a channel you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalUnsubscribe to channels, Either Channels or ChannelGroups is required
    ChannelGroupsArrayOptionalUnsubscribe to channel groups, Either channels or channelGroup is required
    ExecuteCommandYesCommand that will execute Unsubscribe.
Unsubscribe from a channel:
pubnub.Unsubscribe<string>()
     .Channels(new string[] {
        "my_channel"
     })
     .Execute();
The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.
The output below demonstrates the response to a successful call:
{
	"action" : "leave"
}
  1. pubnub.Unsubscribe<string>()
        .Channels(new string[] { 
            "ch1",
            "ch2", 
            "ch3" 
        })
        .ChannelGroups(new string[] {
            "cg1", 
            "cg2", 
            "cg3" 
        })
        .Execute();
    {
    	"action" : "leave"
    }
    
  2. pubnub.Unsubscribe<string>()
        .ChannelGroups(new string[] {
            "cg1",
            "cg2",
            "cg3"
        })
        .Execute();
    {
    	"action": "leave"
    }
    
Unsubscribe from all channels and all channel groups
  • void UnsubscribeAll<string>()
pubnub.UnsubscribeAll<string>();
None

You can be notified of connectivity status, message and presence notifications via the listeners.

Listeners should be added before calling the method.

SubscribeCallbackExt listenerSubscribeCallack = new SubscribeCallbackExt(
    (pubnubObj, message) => { 
        // Handle new message stored in message.Message 
    },
    (pubnubObj, presence) => { 
        // handle incoming presence data 
    },
    (pubnubObj, status) => {
        // the status object returned is always related to subscribe but could contain
        // information about subscribe, heartbeat, or errors
        // use the PNOperationType to switch on different options
        switch (status.Operation) {
            // let's combine unsubscribe and subscribe handling for ease of use
            case PNOperationType.PNSubscribeOperation:
            case PNOperationType.PNUnsubscribeOperation:
                // note: subscribe statuses never have traditional
                // errors, they just have categories to represent the
                // different issues or successes that occur as part of subscribe
                switch (status.Category) {
                    case PNStatusCategory.PNConnectedCategory:
                        // this is expected for a subscribe, this means there is no error or issue whatsoever
                    break;
                    case PNStatusCategory.PNReconnectedCategory:
                        // this usually occurs if subscribe temporarily fails but reconnects. This means
                        // there was an error but there is no longer any issue
                    break;
                    case PNStatusCategory.PNDisconnectedCategory:
                        // this is the expected category for an unsubscribe. This means there
                        // was no error in unsubscribing from everything
                    break;
                    case PNStatusCategory.PNUnexpectedDisconnectCategory:
                        // this is usually an issue with the internet connection, this is an error, handle appropriately
                    break;
                    case PNStatusCategory.PNAccessDeniedCategory:
                        // this means that PAM does allow this client to subscribe to this
                        // channel and channel group configuration. This is another explicit error
                    break;
                    default:
                        // More errors can be directly specified by creating explicit cases for other
                        // error categories of `PNStatusCategory` such as `PNTimeoutCategory` or `PNMalformedFilterExpressionCategory` or `PNDecryptionErrorCategory`
                    break;
                }
            break;
            case PNOperationType.PNHeartbeatOperation:
                // heartbeat operations can in fact have errors, so it is important to check first for an error.
                if (status.Error) {
                    // There was an error with the heartbeat operation, handle here
                } else {
                    // heartbeat operation was successful
                }
            break;
            default:
                // Encountered unknown status type
            break;
        }
    });

pubnub.AddListener(listenerSubscribeCallack);
SubscribeCallbackExt listenerSubscribeCallack = new SubscribeCallbackExt(
    (pubnubObj, message) => { },
    (pubnubObj, presence) => { },
    (pubnubObj, status) => { });

pubnub.AddListener(listenerSubscribeCallack);

// some time later
pubnub.RemoveListener(listenerSubscribeCallack);
CategoriesDescription
PNNetworkIssuesCategory
A subscribe event experienced an exception when running.
PNReconnectedCategory
SDK was able to reconnect to pubnub.
PNConnectedCategory
SDK subscribed with a new mix of channels (fired every time the channel / channel group mix changed).
You can obtain information about the current state of a channel including a list of unique user-ids currently subscribed to the channel and the total occupancy count of the channel by calling the HereNow() function in your application.
To call Here Now you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalThe Channels to get the here now details.
    ChannelGroupsArrayOptionalThe ChannelGroups to get the here now details.
    IncludeStateboolOptionalIf true, the response will include the presence states of the users for Channels/ChannelGroups
    IncludeUUIDsboolOptionalIf true, the response will include the UUIDs of the connected clients.
    AsyncPNCallbackYesPNCallback of type PNHereNowResult
pubnub.HereNow()
    // tailor the next two lines to example
    .Channels(new string[] { 
        "coolChannel",
        "coolChannel2"
     })
    .IncludeUUIDs(true)
    .Async(new PNHereNowResultEx(
        (result, status) => {
            if (status.Error) {
                // handle error
                return;
            }

            if (result.Channels != null && result.Channels.Count > 0) {
                foreach (KeyValuePair<string, PNHereNowChannelData> kvp in result.Channels) {
                    PNHereNowChannelData channelData = kvp.Value;
                    Console.WriteLine("---");
                    Console.WriteLine("channel:" + channelData.ChannelName);
                    Console.WriteLine("occupancy:" + channelData.Occupancy);
                    Console.WriteLine("Occupants:");
                    if (channelData.Occupants != null && channelData.Occupants.Count > 0) {
                        for (int index = 0; index < channelData.Occupants.Count; index++) {
                            PNHereNowOccupantData occupant = channelData.Occupants[index];
                            Console.WriteLine(string.Format("uuid: {0}", occupant.Uuid));
                            Console.WriteLine(string.Format("state:{1}", (occupant.State != null) ?
                            pubnub.JsonPluggableLibrary.SerializeToJsonString(occupant.State) : ""));
                        }
                    }
                }
            }
        }
    ));
The HereNow() operation returns a PNHereNowResult which contains the following properties:
Property NameTypeDescription
TotalChannelsintTotal Channels.
TotalOccupancyintTotal Occupancy.
ChannelsDictionary<string, PNHereNowChannelData>A map with values of PNHereNowChannelData for each channel. See PNHereNowChannelData for more details.
Property NameTypeDescription
ChannelNamestringChannel name.
OccupancyintOccupancy of the channel.
OccupantsList<PNHereNowOccupantData>A list of PNHereNowOccupantData, see PNHereNowOccupantData for more details.
Property NameTypeDescription
UuidstringUUIDs of the user.
StateobjectState of the user.
  1. pubnub.HereNow()
        .Channels(new string[] {
            // who is present on those channels?
            "my_channel"
        }) 
        .IncludeState(true) // include state with request (false by default)
        .IncludeUUIDs(true) // if false, only shows occupancy count
        .Async(new PNHereNowResultEx(
            (result, status) => {
                //handle it
            }
        ));
    {
    	"status" : 200,
    	"message" : "OK",
    	"service" : "Presence",
    	"uuids" : [
    		{
    			"uuid" : "myUUID0"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 15
    				}
    			},
    			"uuid" : "myUUID1"
    		},
    		{
    			"uuid" : "b9eb408c-bcec-4d34-b4c4-fabec057ad0d"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 15
    				}
    			},
    			"uuid" : "myUUID2"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 24
    				}
    			},
    			"uuid" : "myUUID9"
    		}
    	],
    	"occupancy" : 5
    }
    
  2. You can return only the occupancy information for a single channel by specifying the channel and setting uuids to false:
    pubnub.HereNow()
        .Channels(new string[] {
             // who is present on those channels?
            "my_channel"
        })
        .IncludeState(false) // include state with request (false by default)
        .IncludeUUIDs(false) // if false, only shows occupancy count
        .Async(new PNHereNowResultEx(
            (result, status) => {
                //handle it
            }
        ));
    {
        "status": 200,
        "message": "OK",
        "payload": {
            "channels": {
                "81d8d989-b95f-443c-a726-04fac323b331": { 
                    "uuids": [ "70fc1140-22b5-4abc-85b2-ff8c17b24d59" ], 
                    "occupancy": 1 
                },
                "81b7a746-d153-49e2-ab70-3037a75cec7e": { 
                    "uuids": [ "91363e7f-584b-49cc-822c-52c2c01e5928" ],
                    "occupancy": 1
                },
                "c068d15e-772a-4bcd-aa27-f920b7a4eaa8": { 
                    "uuids": [ "ccfac1dd-b3a5-4afd-9fd9-db11aeb65395" ],
                    "occupancy": 1
                }
            },
            "total_channels": 3,
            "total_occupancy": 3
        },
        "service": "Presence"
    }
    
  3. You can return the list of uuids and occupancy for all channels by omitting the channel:
    pubnub.HereNow()
        .Channels(new string[] { 
             // who is present on those channels?
            "my_channel"
        })
        .IncludeState(false) // include state with request (false by default)
        .IncludeUUIDs(true) // if false, only shows occupancy count
        .Async(new PNHereNowResultEx(
            (result, status) => {
                //handle it
            }
        ));
    {
        "total_channels" : 2,
        "total_occupancy" : 3,
        "channels" : {
            "lobby" : {
                "occupancy" : 1,
                "uuids" : [
                    "dara01"
                ]
            },
            "game01" : {
                "occupancy" : 2,
                "uuids" : [
                    "jason01",
                    "jason02"
                ]
            }
        }
    }
    
  4. You can return only the occupancy information (Global Here Now) by omitting the channel name
    pubnub.HereNow()
        .IncludeState(true) // include state with request (false by default)
        .IncludeUUIDs(true) // if false, only shows occupancy count
        .Async(new DemoHereNowResult());
    
    public class DemoHereNowResult : PNCallback<PNHereNowResult> {
        public override void OnResponse(PNHereNowResult result, PNStatus status) {
        }
    };
    {
        "status": 200,
        "message": "OK",
        "payload": {
            "channels": {
                "81d8d989-b95f-443c-a726-04fac323b331": { 
                    "uuids": [ "70fc1140-22b5-4abc-85b2-ff8c17b24d59" ], 
                    "occupancy": 1 
                },
                "81b7a746-d153-49e2-ab70-3037a75cec7e": { 
                    "uuids": [ "91363e7f-584b-49cc-822c-52c2c01e5928" ],
                    "occupancy": 1
                },
                "c068d15e-772a-4bcd-aa27-f920b7a4eaa8": { 
                    "uuids": [ "ccfac1dd-b3a5-4afd-9fd9-db11aeb65395" ],
                    "occupancy": 1
                }
            },
            "total_channels": 3,
            "total_occupancy": 3
        },
        "service": "Presence"
    }
    
  5. pubnub.HereNow()
        .ChannelGroups(new string[] {
            // who is present on channel groups?    
            "cg1",
            "cg1",
            "cg3"
        })
        .IncludeState(true) // include state with request (false by default)
        .IncludeUUIDs(true) // if false, only shows occupancy count
        .Async(new DemoHereNowResult());
    
    public class DemoHereNowResult : PNCallback<PNHereNowResult> {
        public override void OnResponse(PNHereNowResult result, PNStatus status) {
        }
    };
    {
    	occupancy : 4,
    	uuids : ['123123234t234f34fq3dq', '143r34f34t34fq34q34q3', '23f34d3f4rq34r34rq23q', 'w34tcw45t45tcw435tww3']
    }
    
You can obtain information about the current list of channels to which a uuid is subscribed to by calling the WhereNow() function in your application.
 
If the app is killed/crashes and restarted (or the page containing the PubNub instance is refreshed on the browser) within the heartbeat window no timeout event is generated.
To call WhereNow() you can use the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    AsyncCommandYesExecute as Async.
You simply need to define the uuid and the callback function to be used to send the data to as in the example below.
pubnub.WhereNow()
    .Async(new PNWhereNowResultExt(
        (result, status) => {
            // returns a pojo with channels
            // channel groups which I am part of.
        }
    ));
The WhereNow() operation returns a PNWhereNowResult which contain the following property:
Property NameTypeDescription
ChannelsList<string>The list of channels where the UUID is present.
pubnub.WhereNow()
    .Uuid("some-other-uuid") // uuid of the user we want to spy on.
    .Async(new DemoWhereNowResult());

public class DemoWhereNowResult : PNCallback<PNWhereNowResult> {
    public override void OnResponse(PNWhereNowResult result, PNStatus status) {
        // returns a pojo with channels
        // channel groups which "some-other-uuid" part of.
    }
};
The state API is used to set/get key/value pairs specific to a subscriber Uuid.
State information is supplied as a Generic Dictionary object(Dictionary<string, object>) of key/value pairs.
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalChannels to set state.
    ChannelGroupsArrayOptionalChannelGroups to set state.
    StateDictionary<string, object>OptionalState to set.
    AsyncPNCallbackYesPNCallback of type PNSetStateResult.
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalChannel name to fetch the state.
    ChannelGroupsArrayOptionalChannelGroups name to fetch the state.
    UuidstringOptionalUuid
    AsyncPNCallbackYesPNCallback of type PNGetStateResult.
Dictionary<string, object> myState = new Dictionary<string, object>();
myState.Add("age", 20);
 
pubnub.SetPresenceState()
    .Channels(new string[] {
        "ch1",
        "ch2",
        "ch3"
    })
    .State(myState)
    .Async(new PNSetStateResultExt(
        (result, status) => {
            // handle set state response
        }
    ));
pubnub.GetPresenceState()
    .Channels(new string[] {
        // channels to fetch state for
        "ch1",
        "ch2",
        "ch3"
    })
    .ChannelGroups(new string[] {
        // channel groups to fetch state for
        "cg1",
        "cg2",
        "cg3"
    }) 
    .Uuid("suchUUID") // uuid of user to fetch, or for own uuid
    .Async(new PNGetStateResultExt(
        (result, status) => {
            // handle response
        }
    ));
The SetPresenceState() operation returns a PNSetStateResult which contains the following property:
Property NameTypeDescription
StateDictionary<string, object>Dictionary of UUIDs and the user states.
The GetPresenceState() operation returns a PNGetStateResult which contains the following property:
Property NameTypeDescription
StateByUUIDDictionary<string, object>Dictionary of UUIDs and the user states.
  1. Dictionary<string, object> myState = new Dictionary<string, object>();
    myState.Add("age", 20);
    
    pubnub.SetPresenceState()
        .ChannelGroups(new string[] {
            // apply on those channel groups
            "cg1",
            "cg2",
            "cg3"
        })
        .Channels(new string[] {
            // apply on those channels
            "ch1",
            "ch2",
            "ch3" 
        })
        .State(myState) // the new state   
        .Async(new DemoPNSetStateResult());
    
    public class DemoPNSetStateResult : PNCallback<PNSetStateResult> {
        public override void OnResponse(PNSetStateResult result, PNStatus status) {
            // on new state for those channels
        }
    };
    The above code would return the following response to the client:
    {
    	first   : "Robert",
    	last    : "Plant",
    	age     : 59,
    	region  : "UK"
    }
    
This function establishes access permissions for PubNub Access Manager (PAM) by setting the read or write attribute to true. A grant with read or write set to false (or not included) will revoke any previous grants with read or write set to true.
Permissions can be applied to any one of two levels:
  1. Channel level privileges are based on a combination of SubscribeKey and channel name.
  2. User level privileges are based on the combination of SubscribeKey, channel and AuthKeys.
When a user attempts to access a PubNub resource, PAM will evaluate any existing rules using the following order of precedence before access to a channel is granted to the user:
  1. User Level - As a final step PAM evaluates the attributes at the User level. If an attribute is set to true for SubscribeKey, channel and AuthKeys, access is granted for that attribute.
 
If an argument of the grant is not provided, an expected default will be assumed.
  • read and write arguments default to false
  • no AuthKeys results in channel-level grant
  • no channel results in application-level grant
No Permissions - If no permissions were granted at any of the three levels, the user will be denied access to the PubNub resource and receive a 403 error message. This is the default behavior for a PAM enabled application.
 
Note that privileges specifically granted to an application's SubscribeKey always take precedence over privileges granted to channel or AuthKeys. Therefore an application that requires authentication at the userlevel should not grant access at either the Application or Channel levels.
  • History: To access historical messages you must grant full read access at either the SubscribeKey or channel level. When a user has the appropriate permissions they can access any data stored. If they do not have access a 403 will be returned by PAM.
  • Presence: To grant access to Presence for a particular channel name you must also allow read and write access to the presence channel name which is specified by adding the -pnpres suffix to the name. Also note that a leave will fail in the case where a user's grant expires while connected. An HTTP 403 will be returned.
  • APNS: Standard permissions are required for publishing.
The duration of permission set with Grant() are controlled by setting a time-to-live(ttl). If a ttl is not specified it is automatically set to 1440 minutes by default. Once the ttl associated with an entry in PAM has expired, the read and write attributes are immediately set to false for that entry in the PAM table.
 
PAM grant or revoke requests must be less than ~32KB at a time, or the client will return an error. For requests greater than 32KB, break them into smaller batched requests.
 
When the message size exceeds 32KB the server returns the HTTP Error code 500, instead of the correct error code 414.
To Grant Permissions on a Channel you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    ChannelsArrayOptionalThe Channels to grant access.
    ChannelGroupsArrayOptionalThe ChannelGroups to grant access.
    AuthKeysArrayOptionalAuth keys
    WriteboolOptionalWrite permission.
    ManageboolOptionalManage permission.
    ReadboolOptionalRead permission.
    TTLlongOptionalTime to live for permission to be valid
    AsyncPNCallbackYesPNCallback of type PNAccessManagerGrantResult
pubnub.Grant()
    .Channels(new string[]{
        //channels to allow grant on
        "ch1",
        "ch2",
        "ch3"
    })
    .ChannelGroups(new string[] {
        // groups to allow grant on
        "cg1",
        "cg2",
        "cg3"
     })
    .AuthKeys(new string[] {
        // the keys we are provisioning
        "key1",
        "key2",
        "key3"
    })
    .Write(true) // allow those keys to write (false by default)
    .Manage(true) // allow those keys to manage channel groups (false by default)
    .Read(true) // allow keys to read the subscribe feed (false by default)
    .TTL(12337) // how long those keys will remain valid (0 for eternity)
    .Async(new PNAccessManagerGrantResultExt(
        (result, status) => {
            // PNAccessManagerGrantResult is a parsed and abstracted response from server
        }
    ));
The Grant() operation returns a PNAccessManagerGrantResult which contains the following properties:
Property NameTypeDescription
LevelstringSubkey or channel level.
TtlintTtl of grant.
SubscribeKeystringThe SubscribeKey.
ChannelsDictionary<string, Dictionary<string, PNAccessManagerKeyData>>Access rights per channel. See PNAccessManagerKeyData for more details.
ChannelGroupsDictionary<string, Dictionary<string, PNAccessManagerKeyData>>Access rights per channel group. See PNAccessManagerKeyData for more details.
Property NameTypeDescription
ReadEnabledbooltrue if the user has read rights.
WriteEnabledbooltrue if the user has write rights.
ManageEnabledbooltrue if the user has manage rights.
  1. pubnub.Grant()
        .Channels(new string[] {
            "my_channel"
        })
        .Write(true) 
        .Read(false) 
        .AuthKeys(new string[] {
            "my_ro_authkey"
        }) 
        .TTL(5) 
        .Async(new PNAccessManagerGrantResultExt(
            (result, status) => {
                // PNAccessManagerGrantResult is a parsed and abstracted response from server
            }
        ));
    The above code would return the following response to the client:
    {
    	"status" : 200,
    	"message" : "Success",
    	"payload" : {
    		"ttl" : 5,
    		"auths" : {
    			"my_ro_authkey" : {
    				"r" : 1,
    				"w" : 0
    			}
    		},
    		"subscribe_key" : "my_subkey",
    		"level" : "user",
    		"channel" : "my_channel"
    	},
    	"service" : "Access Manager"
    }
    
  2. pubnub.Grant()
        .Channels(new string[] {
            "my_channel-pnpres"
        })
        .Write(true) 
        .Read(true) 
        .Async(new PNAccessManagerGrantResultExt(
            (result, status) => {
                // PNAccessManagerGrantResult is a parsed and abstracted response from server
            }
        ));
  3. pubnub.Grant()
        .ChannelGroups(new string[] {
            "cg1",
            "cg2",
            "cg3"
        })
        .AuthKeys(new string[] {
            "key1",
            "key2",
            "key3"
        })
        .Write(true)
        .Manage(true)
        .Read(true)
        .TTL(12337)
        .Async(new PNAccessManagerGrantResultExt(
            (result, status) => {
                // PNAccessManagerGrantResult is a parsed and abstracted response from server
            }
        ));
    The above code would return the following response to the client:
    {
        "status":200,
        "message":"Success",
        "payload":{
            "ttl":5,
            "auths":{
                "my_rw_authkey":{
                    "r":1,
                    "w":1
                }
            },
            "subscribe_key":"my_subkey",
            "level":"user",
            "channel":"my_channel"
        },
        "service":"Access Manager"
    }
    
  4. To perform a first level wildcard grant for channel groups you need to specifying : (colon) as the parameter for channelGroups. This will ensure that users can read or manage all channel groups.
    pubnub.Grant()
        .ChannelGroups(new string[] {
            ":"
        })
        .Async(new PNAccessManagerGrantResultExt(
            (result, status) => {
                // PNAccessManagerGrantResult is a parsed and abstracted response from server
            }
        ));
This function adds a channel to a channel group.
Adding Channels is accomplished by using the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelGroupstringYesThe ChannelGroup to add the channels to.
    ChannelsArrayYesThe Channels to add to the channel group.
    AsyncPNCallbackYesPNCallback of type PNChannelGroupsAddChannelResult.
pubnub.AddChannelsToChannelGroup()
    .ChannelGroup("cg1")
    .Channels(new string[] { 
        "ch1", 
        "ch2", 
        "ch3"
    })
    .Async(new PNChannelGroupsAddChannelResultExt(
        (result, status) => {                     
        }
    ));
{
    "service" : "channel-registry",
    "status"  : 200,
    "error"   : false,
    "message" : "OK"
}
This function lists all the channels of the channel group.
Listing Channels is accomplished by using the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelGroupstringYesChannel group to fetch the channels.
    AsyncPNCallbackYesPNCallback of type PNChannelGroupsAllChannelsResult.
pubnub.ListChannelsForChannelGroup()
    .ChannelGroup("cg1")
    .Async(new PNChannelGroupsAllChannelsResultExt(
        (result, status) => {
        }
    ));
The ListChannelsForChannelGroup() operation returns a PNChannelGroupsAllChannelsResult which contains the following property:
Property NameTypeDescription
ChannelsList<string>List of channels of a channel group.
This function removes the channels from the channel group.
Removing Channels is accomplished by using the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelGroupstringYesSpecifies ChannelGroup to remove the channels from.
    ChannelsArrayYesThe Channels to remove from the channel group.
    AsyncPNCallbackOptionalPNCallback of type PNChannelGroupsRemoveChannelResult.
pubnub.RemoveChannelsFromChannelGroup()
    .ChannelGroup("family")
    .Channels(new string[] {
        "son"
    })
    .Async(new PNChannelGroupsRemoveChannelResultExt(
        (result, status) => {
        }
    ));
{
	"status" : 200,
	"message" : "OK",
	"service" : "channel-registry",
	"error" : False
}
This function removes the channel group.
Deleting Channel Group is accomplished by using the following method(s) in the C# V4 SDK:
  1. ParameterTypeRequiredDescription
    ChannelGroupstringYesSpecifies ChannelGroup to remove.
    AsyncPNCallbackOptionalPNCallback of type PNChannelGroupsDeleteGroupResult.
pubnub.DeleteChannelGroup()
    .ChannelGroup("family")
    .Async(new PNChannelGroupsDeleteGroupResultExt(
        (result, status) => {
        }
    ));
{
	"status" : 200,
	"message" : "OK",
	"service" : "channel-registry",
	"error" : False
}
This function fetches historical messages of a channel.
PubNub Storage/Playback Service provides real-time access to an unlimited history for all messages published to PubNub. Stored messages are replicated across multiple availability zones in several geographical data center locations. Stored messages can be encrypted with AES-256 message encryption ensuring that they are not readable while stored on PubNub's network.
It is possible to control how messages are returned and in what order, for example you can:
  • Search for messages starting on the newest end of the timeline (default behavior - Reverse = false)
  • Search for messages from the oldest end of the timeline by setting Reverse to true.
  • Page through results by providing a Start OR End time token.
  • Retrieve a slice of the time line by providing both a Start AND End time token.
  • Limit the number of messages to a specific quantity using the Count parameter.
 
Start & End parameter usage clarity:
If only the Start parameter is specified (without End), you will receive messages that are older than and up to that Start timetoken value.
If only the End parameter is specified (without Start) you will receive messages that match that End timetoken value and newer.
Specifying values for both Start and End parameters will return messages between those timetoken values (inclusive on the End value).
Keep in mind that you will still receive a maximum of 100 messages even if there are more messages that meet the timetoken values. Iterative calls to history adjusting the Start timetoken is necessary to page through the full set of results if more than 100 messages meet the timetoken values.
To run History you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    ChannelstringYesSpecifies Channelto return history messages from.
    ReverseboolOptionalSetting to true will traverse the time line in reverse starting with the oldest message first.
    IncludeTimetokenboolOptionalWhether event dates time tokens should be included in response or not.
    StartlongOptionalTime token delimiting the Start of time slice (exclusive) to pull messages from.
    EndlongOptionalTime token delimiting the End of time slice (inclusive) to pull messages from.
    CountintOptionalSpecifies the number of historical messages to return.
    AsyncPNCallbackYesPNCallback of type PNHistoryResult.
Retrieve the last 100 messages on a channel:
pubnub.History()
    .Channel("history_channel") // where to fetch history from
    .Count(100) // how many items to fetch
    .Async(new PNHistoryResultExt(
        (result, status) => {
        }
    ));
The History() operation returns a PNHistoryResult which contains the following properties:
Property NameTypeDescription
MessagesList<PNHistoryItemResult>List of messages of type PNHistoryItemResult. See PNHistoryItemResult for more details.
StartTimetokenlongStart timetoken.
EndTimetokenlongEnd timetoken.
Property NameTypeDescription
TimetokenlongTimetoken of the message.
EntryobjectMessage.
  1. pubnub.History()
        .Channel("my_channel") // where to fetch history from
        .Count(3) // how many items to fetch
        .Reverse(true) // should go in reverse?
        .Async(new PNHistoryResultExt(
            (result, status) => {
            }
        ));
     [
    	["Pub1","Pub2","Pub3"],
    	13406746729185766,
    	13406746780720711
    ]
    
  2. pubnub.History()
        .Channel("my_channel") // where to fetch history from
        .Start(13847168620721752L) // first timestamp
        .Reverse(true) // should go in reverse?
        .Async(new DemoHistoryResult());
    
    public class DemoHistoryResult : PNCallback<PNHistoryResult> {
        public override void OnResponse(PNHistoryResult result, PNStatus status) {
        }
    };
     [
    	["Pub3","Pub4","Pub5"],
    	13406746780720711,
    	13406746845892666
    ]
    
  3. pubnub.History()
        .Channel("my_channel") // where to fetch history from
        .Count(100) // how many items to fetch
        .Start(-1) // first timestamp
        .End(13847168819178600L) // last timestamp
        .Reverse(true) // should go in reverse?
        .Async(new DemoHistoryResult());
    
    public class DemoHistoryResult : PNCallback<PNHistoryResult> {
        public override void OnResponse(PNHistoryResult result, PNStatus status) {
        }
    };
    [
    	["Pub3","Pub4","Pub5"],
    	13406746780720711,
    	13406746845892666
    ]
    
  4.  
    Usage!
    You can call the method by passing 0 or a valid time token as the argument.
    public class PubnubRecursiveHistoryFetcher {
        private static Pubnub pubnub;
    
        public abstract class CallbackSkeleton {
            public abstract void HandleResponse(PNHistoryResult result);
        }
    
        public PubnubRecursiveHistoryFetcher() {
            // NOTICE: for demo/demo pub/sub keys Storage & Playback is disabled,
            // so use your pub/sub keys instead
            PNConfiguration pnConfiguration = new PNConfiguration();
            pnConfiguration.SubscribeKey = "demo";
            pubnub = new Pubnub(pnConfiguration);
        }
    
        static public void Main() {
            PubnubRecursiveHistoryFetcher fetcher = new PubnubRecursiveHistoryFetcher();
            GetAllMessages(new DemoCallbackSkeleton());
        }
    
        public static void GetAllMessages(CallbackSkeleton callback) {
            GetAllMessages(-1L, callback);
        }
    
        public static void GetAllMessages(long startTimestamp, CallbackSkeleton callback) {
            CountdownEvent latch = new CountdownEvent(1);
    
            pubnub.History()
                .Channel("history_channel") // where to fetch history from
                .Count(100) // how many items to fetch
                .Start(startTimestamp) // first timestamp
                .Async(new DemoHistoryResult(callback));
        }
    
        public class DemoHistoryResult : PNCallback<PNHistoryResult> {
            CallbackSkeleton internalCallback;
            public DemoHistoryResult(CallbackSkeleton callback) {
                this.internalCallback = callback;
            }
            public override void OnResponse(PNHistoryResult result, PNStatus status) {
                if (!status.Error && result != null && result.Messages != null && result.Messages.Count > 0) {
                    Console.WriteLine(result.Messages.Count);
                    Console.WriteLine("start:" + result.StartTimeToken.ToString());
                    Console.WriteLine("end:" + result.EndTimeToken.ToString());
    
                    internalCallback.HandleResponse(result);
                    GetAllMessages(result.EndTimeToken, this.internalCallback);
                }
            }
        };
    
        public class DemoCallbackSkeleton : CallbackSkeleton {
            public override void HandleResponse(PNHistoryResult result) {
                //Handle the result
            }
        }
    }
  5. pubnub.History()
        .Channel("history_channel") // where to fetch history from
        .Count(100) // how many items to fetch
        .IncludeTimetoken(true) // include timetoken with each entry
        .Async(new DemoHistoryResult());
    
    public class DemoHistoryResult : PNCallback<PNHistoryResult> {
        public override void OnResponse(PNHistoryResult result, PNStatus status) {
        }
    };
Enable push notifications on provided set of channels.
To run Adding Device to Channel you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    PushTypePNPushTypeYesAccepted values: PNPushType.GCM, PNPushType.APNS, PNPushType.MPNS.
    ChannelsArrayYesAdd push notifications on the specified Channels.
    DeviceIdstringYesDevice id.
    AsyncPNCallbackYesPNCallback of type PNPushAddChannelResult.
pubnub.AddPushNotificationsOnChannels()
    .PushType(PNPushType.GCM)
    .Channels(new string[] { 
        "ch1",
        "ch2",
        "ch3"
    })
    .DeviceId("googleDevice")
    .Async(new DemoPushAddChannel());

public class DemoPushAddChannel : PNCallback<PNPushAddChannelResult> {
    public override void OnResponse(PNPushAddChannelResult result, PNStatus status) {
    }
}
The AddPushNotificationsOnChannels() does not return actionable data, be sure to check the status object on the outcome of the operation by checking the status.isError().
Request for all channels on which push notification has been enabled using specified pushToken.
To run Listing Channels For Device you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    DeviceIdstringYesDevice id.
    PushTypePNPushTypeYesAccepted values: PNPushType.GCM, PNPushType.APNS, PNPushType.MPNS.
    AsyncPNCallbackYesPNCallback of type PNPushListProvisionsResult.
pubnub.AuditPushChannelProvisions()
    .DeviceId("googleDevice")
    .PushType(PNPushType.GCM)
    .Async(new DemoPushListProvisionChannel());

public class DemoPushListProvisionChannel : PNCallback<PNPushListProvisionsResult> {
    public override void OnResponse(PNPushListProvisionsResult result, PNStatus status) {
    }
}
The AuditPushChannelProvisions() operation returns a PNPushListProvisionsResult which contains the following property:
Property NameTypeDescription
ChannelsList<string>List of channels subscribed for push notifications.
Disable push notifications on provided set of channels. If nil will be passed as channels then client will remove push notifications from all channels which associated with pushToken.
To run Removing Device From Channel you can use the following method(s) in the C# V4 SDK
  1. ParameterTypeRequiredDescription
    DeviceIdstringYesDevice id.
    ChannelsArrayYesRemove push notifications on the specified Channels.
    PushTypePNPushTypeYesAccepted values: PNPushType.GCM, PNPushType.APNS, PNPushType.MPNS.
    AsyncPNCallbackYesPNCallback of type PNPushRemoveChannelResult.
pubnub.RemovePushNotificationsFromChannels()
    .DeviceId("googleDevice")
    .Channels(new string[] { 
        "ch1",
        "ch2", 
        "ch3" 
    })
    .PushType(PNPushType.GCM)
    .Async(new DemoPushRemoveChannel());

public class DemoPushRemoveChannel : PNCallback<PNPushRemoveChannelResult> {
    public override void OnResponse(PNPushRemoveChannelResult result, PNStatus status) {
    }
}
The RemovePushNotificationsFromChannels() does not return actionable data, be sure to check the status object on the outcome of the operation by checking the status.isError().
This function will return a 17 digit precision Unix epoch.
 
Timetoken
The timetoken is constructed using the following algorithm:
timetoken = (Unix epoch time in seconds) * 10000000
Example of creating a timetoken for a specific time & date
08/19/2013 @ 9:20pm in UTC = 1376961606
timetoken = 1376961606 * 10000000
timetoken = 13769616060000000
To fetch Time you can use the following method(s) in C# V4 SDK
  1. ParameterTypeRequiredDescription
    AsyncPNCallbackYesPNCallback of type PNTimeResult.
pubnub.Time()
    .Async(new PNTimeResultExt(
        (result, status) => {
            // handle time result.
        }
    ));
The Time operation returns a PNTimeResult which contains the following property:
Property NameTypeDescription
TimetokenlongReturns a long representation of current time token.
Returns all the subscribed channels in a List of type String..
To Get Subscribed Channels you can use the following method(s) in the C# V4 SDK:
  1. List<string> GetSubscribedChannels()
List<string> channels = pubnub.GetSubscribedChannels();
List<String>
["channel1", "channel2"]
Returns all the subscribed channel groups in a List of type String..
To Get Subscribe Channel Groups you can use the following method(s) in the C# V4 SDK
  1. List<string> GetSubscribedChannelGroups()
List<string> groups = pubnub.GetSubscribedChannelGroups();
List<String>
["channelGroup1", "channelGroup2"]
Destroy frees up the threads and allows for clean exit.
  1. destroy()
pubnub.Destroy();
None