PubNub is a client-to-client push service in the cloud.
Connect Everything to Everything; literally!
This is a cloud-based service for broadcasting Real-time messages
to millions of web and mobile clients simultaneously.

PubNub Version 3.1

The current version number for communication with PubNub Cloud is 3.1.

Process for Announcing New/Updated API.

When a PubNub Client API is updated or a brand new PubNub Client
API becomes available, tell everyone!:

PubNub API Specification

Use this section of the README to review the current specification for
PubNub Cloud Client Libraries.
The pseudocode will guide you in learning how each
client library must act in order to properly support the
breadth of features powered by PubNub Cloud.
Most client libraries are already written!
So go check out the list of libraries already available.

Rules of PubNub Client Lib

Must be able to communicate with EVERY other PubNub Client Lib.

Must be Non-blocking (Asynchronous) on all I/O.

Must use single Dictionary/Object as Parameter for all methods.

Must follow guides in this README file including method param patterns.

Includes a Full Unit Test with a test of each method.

Includes Quick Usage Doc with Example Copy/Paste Code for each Method.

The Lib must be only ONE file. (i.e. pubnub.py, Pubnub.java, Pubnub.cs)

Okay to include Vendor Files.

Robustness of API

The client must be fault tolerant
and never throw exceptions or errors.
If a message was unable to be delivered,
you must return an unsuccessful value.
If an error code was returned of any kind from
the PubNub Cloud, then you must inform the failure
by returning an unsuccessful response.
If a connection was lost, the connection
must continuously attempt to be re-established.

Ubiquity

All Client APIs must be able to communicate with
every other Client API in every supported mode including
but not limited to:

AES Encryption

Signed HMAC SHA256 messages

TCP Sockets

HTTPS

HTTP

For example, This means that PHP and Ruby will always be able
communicate via Publish/Subscribe.
Same goes for Python and JavaScript and every other language.

SUBSCRIBE()

Listen for messages on a specified channel.
Register events for receiving messages, connecting,
disconnecting and reconnecting after an unintended disconnect.

Never Fire the disconnect event if the network is avaiable.
Only fire the disconnect event if the internet is unreachable.
Note that periodically PubNub will purge connections.
However it is the duty of the Client API to re-establish the connection
instnatly when this happens.
It is wrong to fire the disconnect event if PubNub is reacable.

HISTORY()

Cryptography Guide

PubNub Cryptography in JavaScript

PubNub Crypto
demonstrates with PubNub Cryptography for sensitive data.
Use this page and source code to provide high
levels of security for data intended to be private
and unreadable.

The Cipher Key specifies the particular transformation
of plaintext into ciphertext, or vice versa during decryption.
The Cipher Key exchange must occur on an external system
outside of PubNub in order to maintain secrecy of the key.

Make use of the design patterns shown here when implementing a
PubNub Client Library. However you must follow directly
the Interface shown in this Doc when utilizing
AES Encryption.
Search for cipher_key to find interface guide.

Connection Pooling Guide for APIs

As a rule of performance: an always-on socket connection
pre-established will provide faster message delivery
and receipt.
Establishing a socket pool is simple when using
socket loop libraries such as Ruby::EventMachine
or C LibEvent.

As an alternative, you may use an Async::HTTP Lib
which provides socket pooling functionality for you.

The following Pseudocode will provide insight
into the requirement for socket connection pooling:

Each channel connection will get its own dedicated
socket to which an always-on

Documentation Rules

Must fit into a single page README.md file.

Must be inside README.md within the API directory.

May not be more than one file.

API Directory Structure Rules

Must be simple to start with copy/paste easy.

Include all required vendor libs in sub-directories.

HTTPS TLS SSL 2048bit Encryption

HTTPS is recommended for the highest level of security for
REST requests to PubNub. Using REST over HTTPS is not required.
However for secure communication, you should make sure the client or
REST toolkit you're using is configured to use SSL.
The PubNub Cloud service will continue to support both HTTP and HTTPS.

Message Signing Guide with HMAC/SHA256

In order to provide Origin Authenticity and High Level of Security,
Secret Key
When accessing Amazon SimpleDB using one of the AWS SDKs, the SDK handles the authentication process for you. For a list of available AWS SDKs supporting Amazon SimpleDB, see Available Libraries.

However, when accessing Amazon SimpleDB using a REST request, you must provide the following items so the request can be authenticated.

REST Interface

HTTP HEADERS

Include these required headers with each reqeust to the
PubNub HTTP REST interface.

Example Headers:

FULL HTTP Request Example:

There are may possible User-Agent's.
The following is an accepted style format
for the value of User-Agent header:

PHP

JavaScript

Node.JS

Ruby

Ruby-Rhomobile

Python

Python-Twisted

Python-Tornado

C-LibEV

C-LibEvent

C-Qt

VB

C#

Java

Java-Android

Erlang

Titanium

Corona

C-Arduino

C-Unity

C#-Mono

Lua

Obj-C-iOS

C#-WP7

Cocoa

Perl5

Perl6

Go-Google

Bash

Haskell

TIME()

URL Params:

/time/0

Request Example:

GET /time/0 HTTP/1.1

Response:

[7529152783414]

SUBSCRIBE()

This is a special HTTP Request that holds the connection
and response until a message is published or the connection timer
fires a timetoken update.

The Subscribe Process Lifecycle

Send First Request.

Receive a snazzy new TimeToken.

Send Second Request with Last Received new snazzy TimeToken.

Receive a response after X Minutes with array of Messages (may be empty) and new TimeToken.

Repeat #2-#5 forever until UNSUBSCRIBE()

URL Params:

/subscribe/subscribe_key/channel/0/timetoken

First Request:

GET /subscribe/demo/my-channel/0/0 HTTP/1.1

First Response:

[[],"7529152783414"]

Second Request:

GET /subscribe/demo/my-channel/0/7529152783414 HTTP/1.1

Response When Message Transmitted:

[[MSG,MSG,MSG],"75291527861853"]

Response when Timer Update Fires with New TimeToken

[[],"75291527861853"]

PUBLISH()

URL Params:

/publish/pub-key/sub-key/sha256-signature/channel/0/json

Request Example:

GET /publish/demo/demo/e0991b12871de57b333fd0c992f7d3112577cf62/my-channel/0/{"msg":"hi"} HTTP/1.1

Response:

[1,"Demo"]

Response Codes:

The Publish Response always returns success transmission details.
The First element of the response Array is a bool value either 0 or 1.
0 means failure and 1 means successful transmission.
If the response code is 0, then the transmission has failed.
In the condition of a failed transmission, an explanation is provided
in the second element of the response array.

Successful Transmission:

[1,"Sent"]

Failed Transmission:

[0,"Reason for Failure Shown Here"]

Possible Failure Reasons:

"Disconnected" - The network has gone away.

"Message Too Big" - Max message size exceeded.

"Invalid Publish Key" - Wrong Publish Key was Used.

"Invalid Message Signature" - The message was SHA256 Signed incorrectly.

HISTORY()

History API will allow you to fetch previously published messages.
Currently you can only fetch the last 100 messages.
However soon-to-come features will include forever-history fetching.

URL Format:

/history/sub-key/channel/0/limit

Request Example:

GET /history/demo/my-channel/0/100 HTTP/1.1

Response:

[MSG,MSG,MSG]

Asynchronous Mandate

All functions are required to be non-blocking.
All I/O must be Asynchronous.
Threads are okay however SOCKET LOOPS are much preferred.
Examples of Good Socket Loop libs are:

Twisted (Python)

Tornado (Python)

Node.JS (JavaScript)

Event::Machine (Ruby)

LibEvent (C)

LibEV (C)

Any::Event (Perl)

POE::Async (Perl)

Any executed function must not stop the execution stack.
If a return value is needed from a function call,
then a callback function is required to be a parameter
of the function -- and the return value is supplied to the callback.

Pseudocode Logic Requirements

Publish and Subscribe require significant amounts of checks
in order to provide for easy use to the developer using the API.
Show as follows are the Publish and Subscribe functions which
have basic Pseudocode Logic Requirements: