AngularJSAngularJS V4 Publish/Subscribe Tutorial for Realtime Apps

PubNub utilizes a Publish/Subscribe model for real-time data streaming and device signaling which lets you establish and maintain persistent socket connections to any device and push data to global audiences in less than ¼ of a second.
The atomic components that make up a data stream are API Keys, Messages, and Channels.
To build an application that leverages the PubNub Network for Data Streams with Publish and Subscribe, you will need PubNub API Keys which we provide when you Sign-Up.

You will need at the minimum a subscribeKey and publishKey. If a client will only subscribe, and not publish, then the client only need to initialize with the subscribeKey. For clients who will be publishing only, or publishing and subscribing (a client can both publish and subscribe), it will need to initialize with both the subscribeKey and the publishKey.

You only need to supply the publishKey to clients that will publish (send) data to your application over the PubNub network. A read-only client for example would not need to initialize with this key.

 
Although a secretKey is also provided to you along with your publish and subscribe keys in the admin portal, it is not required for plain-old publish and subscribe. You'll only need the secretKey if you are using PAM functionality, which we discuss more in the PAM Feature Tutorial.
A message consists of a channel, and its associated data payload. A publishing client publishes messages to a given channel, and a subscribing client receives only the messages associated with the channels its subscribed to.

PubNub Message payloads can contain any JSON data including Booleans, Strings, Numbers, Arrays, and Objects. Simply publish the native type per your platform, and the clients will JSON serialize the data for you. Subscribers will automatically deserialize the JSON for you into your platform's associated native type.
 
When creating a message, keep these limits in mind:
  • Maximum message size is 32KB
  • The message size includes the channel name
  • The message size is calculated after all URL encoding and JSON serialization has occured. Depending on your data, this could add > 4X the original message size.

Keeping your messages < 1.5KB in size will allow them to fit into a single TCP packet!

For further details please check: https://support.pubnub.com/support/discussions/topics/14000006322

Channels are created on-the-fly, and do not incur any additional charges to use one or many in your application. When you create a PubNub application, all messages will be associated with a channel.

In a unicast (AKA 1:1) design pattern, the channels can be unique for each client in one-to-one communication. For example, user1 subscribes to user1-private, and user2 subscribes to user2-private. Using this pattern, each client listens on a channel which only relevant data to that client is sent. It has the advantage of minimal network usage (each client receives only the data it needs) and minimal processing (no need for filtering unneeded data).

PubNub Galaxy                                                                                                                            
In a multicast (AKA 1:Many) design pattern, a public (AKA system, global, or admin) channel is used for global communications amongst all clients. For example, building off our previous example, while a user can speak to any other user on their private channel, since each client in the application is listening on their private channel AND the public channel, they can receive on either. When receiving a message on the public channel, it may or may not be relevant for that particular receiving client -- to get around this, the client can filter on some sort of key, allowing them to selectively process messages with specific interest to them.

PubNub Pulse
In many cases, based on the use case of your application, the pattern you choose may be unicast, multicast, or a combination. There is no right or wrong pattern to implement, but based on your use case, there may be an optimal, most efficient pattern.
Since the text length of the channel name is counted as part of the entire message, and as such, as part of the maximum message length, it is best to keep the channel name as short as efficiency and utility allows.

Channel names are UTF-8 compatible. Prohibited chars in a channel name are:
  • comma: ,
  • slash: /
  • backslash: \
  • period: .
  • asterisks: *
  • colon: :
  • Include the PubNub library
  • init() - instantiate a PubNub instance.
  • subscribe() - additively subscribe to a specific channel.
  • publish() - send a message on a specific channel.
  • unsubscribe() - additively unsubscribe to a specific channel.

Pubnub Angular service is a wrapper for PubNub JavaScript SDK that adds a few extra features to simplify Angular integrations:

  • Multiple instance behavior: All instances are accessible throughout application via Pubnub service.
  • Events: Delegated methods accept the triggerEvents option which will broadcast certain callback as an AngularJS event.
  • A $pubnubChannel object that seamlessly binds a PubNub channel to a scope variable that gets updated with realtime data and allows you to interact with the channel through dedicated methods.
  • A $pubnubChannelGroup object that provides an easy-to-use interface for channel groups. It stores the incoming messages in containers split by the channel and exposes an interface to directly fetch messages by channel.

You can still use the native Pubnub JavaScript SDK if you feel this will be more suitable for your situation.

Your HTML page will include 2 key libraries:

  • PubNub JavaScript SDK
  • PubNub JavaScript SDK AngularJS Service
  1. Include AngularJS:
     
            <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    
    
  2. Include the latest version of PubNub's Javascript SDK.
  3. Include PubNub's AngularJS SDK:
     
            <script src="<location-of-PubNub-SDK>/pubnub-angular-4.1.0.min.js"></script>
    
<body ng-app="PubNubAngularApp">

Where PubNubAngularApp is the name of the AngularJS module containing your app.

<script src="scripts/app.js"></script>
angular.module('PubNubAngularApp', ["pubnub.angular.service"])

This will make sure that the Pubnub object is available to get injected into your controllers.

<script src="scripts/controllers/main.js"></script>
.controller('MainCtrl', function($scope, Pubnub) { ... });

To learn about Pubnub JavaScript features refer to native Pubnub JavaScript SDK manual. All methods of this SDK are wrapped with Pubnub AngularJS Service.

Native Pubnub JavaScript SDK provides instance creation using Pubnub.init(), which returns new instance with given credentials. In Pubnub AngularJS SDK instances are hidden inside service and are accessible via instance getter. Methods of default instance are mapped directly to Pubnub service just like Pubnub.publish({...}). In most use cases usage of the only default Pubnub instance will be enough, but if you need multiple instances with different credentials, you should use Pubnub.getInstance(instanceName) getter. In this case publish method will looks like Pubnub.getInstance(instanceName).publish({}).

To summarize above let's check out the following 2 examples. Both of them performs the same job - creation of 2 Pubnub instances with different credentials. Publish method is invoked on the defaultInstance and grant method on anotherInstance.

var defaultInstance = new PubNub({
    publishKey: 'your pub key',
    subscribeKey: 'your sub key'
});

defaultInstance.publish(
    {
        message: { 
            such: 'Hello!' 
        },
        channel: 'myChannel'
    },
    function (status, response) {
        if (status.error) {
            console.log(status)
        } else {
            console.log("message Published w/ timetoken", response.timetoken)
        }
    }
);
Pubnub.init({
    publishKey: 'your pub key',
    subscribeKey: 'your sub key'
});

Pubnub.publish(
    {
        message: { 
            such: 'Hello!' 
        },
        channel: 'myChannel'
    },
    function (status, response) {
        if (status.error) {
            console.log(status)
        } else {
            console.log("message Published w/ timetoken", response.timetoken)
        }
    }
);

That's it - you're ready to start using the PubNub AngularJS SDK!

If this PubNub instance will only be subscribing, you only need to pass the subscribeKey to initialize the instance. If this instance will be subscribing and publishing, you must also include the publishKey parameter.
Pubnub.init({
    subscribeKey: "mySubscribeKey",
    publishKey: "myPublishKey",
    ssl: true
})
The channel the messages will be published over is called my_channel. For this example, we want the same instance to both publish and subscribe. To do this, we'll publish a message to the channel, but only after we're sure we've first successfully subscribed to the channel.
The publish() and subscribe() methods are pretty simple to use. For both publish() and subscribe(), the channel attribute defines the channel in use.
For subscribe() the message callback is where received messages are called-back to:
// Subscribe to a channel
Pubnub.addListener({
    status: function(statusEvent) {
        if (statusEvent.category === "PNUnknownCategory") {
            var newState = {
                new: 'error'
            };
            Pubnub.setState(
                { 
                    state: newState 
                }, 
                function (status) {
                    console.log(statusEvent.errorData.message)
                }
            );
        }
    },
    message: function(message) {
        console.log(message)
    }
})

Pubnub.subscribe({
    channels: ['my_channel']
});
 
NOTE: During your application's lifecycle, you can call subscribe() repeatedly to additively subscribe to additional channels.
For publish(), the message attribute contains the data you are sending.
Pubnub.publish(
    {
        message: { 
            such: 'Hello from the PubNub Javascript SDK!'
        },
        channel: 'my_channel'
    }, 
    function (status, response) {
        if (status.error) {
            // handle error
            console.log(status);
        } else {
            console.log("message Published w/ timetoken", response.timetoken);
        }
    }
);

The above code demonstrates how to subscribe, and how to publish. But what if your use-case requires that client instance not only subscribes and publishes, but also that its guaranteed to start publishing only AFTER it's successfully subscribed? -- In other words, you want to guarantee it receives all of its own publishes?

The JavaScript Web client SDK, like many of the PubNub SDKs, is asynchronous -- publish() can, and most likely will, fire before the previously executed subscribe() call completes. The result is, for a single-client instance, you would never receive (via subscribing) the message you just published, because the subscribe operation did not complete before the message was published.

To get around this common case, we can take advantage of the optional connect callback in the subscribe method:

// Publish to a channel, but only 
// after we’ve connected from the subscriber

Pubnub.subscribe({
	channel: 'my_channel',
	message: function(m){console.log(m);},
	connect: Pubnub.publish({
		channel: 'my_channel',
		message: 'Hello from the PubNub Javascript SDK'
	})
});
By following this pattern on a client that both subscribes and publishes when you want to be sure to subscribe to your own publishes, you’ll never miss receiving a message.
While you are subscribed to a channel, you will continue to receive messages published to that channel. To stop receiving messages on a given channel, you must unsubscribe() from the channel.
// Unsubscribe from 'my_channel'

Pubnub.unsubscribe({
	channels : ['my_channel']
});
Like subscribe(), unsubscribe() can be called multiple times to successively remove different channels from the active subscription list.