Presence Service: who's subscribing?

  • Dec 02, 2013
  • Starting Guide

The Realtime Messaging delivers a set of services allowing developers the ability of knowing how many users are subscribing each channel and who they are. All with a few simple API calls. We call it the Presence Services.

Using these services is simple: just enable the presence feature for a given channel (or sub-channel) and call the get presence API whenever you need to know how many users are subscribing it. You can even request their connection’s metadata information so you know who they are.

Enabling the presence feature

Before you can request the presence data for a given channel you must enable it first. You’ll need to know your private key and define if you need the Realtime Messaging Servers to collect the connection’s metadata or not (true or false at the metadata property).

Here is an example using the NodeJS SDK where the presence feature with metadata is enabled for the channel myChannel :

var ortcNodeclient = require('IbtRealTimeSJNode').IbtRealTimeSJNode;
var ortcClient = new ortcNodeclient();

ortcClient.enablePresence({
  applicationKey : '<ORTC_APPLICATION_KEY>',
  channel : 'myChannel', 
  privateKey : '<ORTC_PRIVATE_KEY>', 
  url : 'http://ortc-developers.realtime.co/server/2.1/',
  isCluster : true,
  metadata : true
},

function(error,result){
  if(error){
    console.log('Presence',error);  
  }else{
    console.log('Presence enable',result);
  }       
}); 
    

The same can be achieved using the Realtime PHP SDK:

<?php

	require('./ortc.php');

	// Generate a random string to use as token
	function generateRandomString($length = 10) {
	    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	    $charactersLength = strlen($characters);
	    $randomString = '';
	    for ($i = 0; $i < $length; $i++) {
	        $randomString .= $characters[rand(0, $charactersLength - 1)];
	    }
	    return $randomString;
	}

	$URL = 'https://ortc-developers.realtime.co/server/ssl/2.1';
	$AK = '<ORTC_APPLICATION_KEY>';
	$PK = '<ORTC_PRIVATE_KEY>';

	// Get a random string to use as Realtime token
	$TK = generateRandomString();
	$CH = 'myChannel';

	// Create the Realtime client instance
	$rt = new Realtime( $URL, $AK, $PK, $TK );

	// enable presence with metadata for the channel
    $result = $rt->enable_presence($CH, 1);

?>

NOTE: Enabling the presence feature for a wildcard sub-channel (e.g. myChannel:*) will automatically enable the presence feature for each sub-channel of myChannel.

Requesting the presence data

As soon as the presence feature is enabled for a given channel you can start requesting the presence data for that channel.

Here is an example using the NodeJS SDK where the presence data is requested for the channel myChannel :

var ortcNodeclient = require('IbtRealTimeSJNode').IbtRealTimeSJNode;
var ortcClient = new ortcNodeclient();

ortcClient.presence({
  applicationKey : '<ORTC_APPLICATION_KEY>',
  authenticationToken : '<AUTHENTICATION_TOKEN>',
  isCluster : true,
  url : 'http://ortc-developers.realtime.co/server/2.1/',
  channel : 'myChannel'
  },
  function(error,result){
    if(error){
      console.log('Presence error:',error);
    }else{
      if(result){
        console.log('Number of subscribers',result.subscriptions);  

        for(var metadata in result.metadata){
          console.log(metadata,'-',result.metadata[metadata]);                  
        }
      }else{
        console.log('No subscribers');  
      }             
    }
  }
);
    

Using the JavaScript SDK the same example would be like this:

if (ortcClient.getIsConnected()) {
  presenceData = {
    channel: channel
  };
} else {
  var presenceData = {
    applicationKey: <ORTC_APPLICATION_KEY>,
    authenticationToken: <AUTHENTICATION_TOKEN>,
    isCluster: true,
    url: 'http://ortc-developers.realtime.co/server/2.1/',
    channel: 'myChannel'
  };
}

ortcClient.presence(presenceData,
  function (error, result) {
    if (error) {
      console.log('Presence error: ' + error);
    } else {
      if (result) {
        for (var metadata in result.metadata) {
          console.log(' ' + metadata + ' : ' + result.metadata[metadata]);
        }
        console.log('Number of subscribers: ' + result.subscriptions);
      } else {
        console.log('Number of subscribers: 0');
      }
    }
  });
    

To keep your application secure you’ll need to specify the <AUTHENTICATION_TOKEN> when calling the presence method. This token must include the permission Presence or P for the desired channel (please refer to the Security documentation for more details) otherwise an Invalid Connection will be returned.

The result of the presence method is a JSON object containing the number of connections currently subscribing the channel (subscriptions) as well as their metadata, if enabled by the enable method (metadata[]).

NOTE: Each call to the presence method will be billed as one message.

This is a possible JSON result of the presence method for a channel with 2 subscribers (user_id=1389 and user_id=639). Note that these user id’s are defined by your application at the connection time through the connection metadata property (you can use user id’s to identify each user or use their user/nick names if you prefer, depending of your application needs).

{
    "subscriptions": 2,
    "metadata": {
        "{\"user_id\":\"1389\"}": 1,
        "{\"user_id\":\"639\"}": 1
     }
}
    

NOTE: The subscriptions property will contain the current number of subscribers without any limitation but only a maximum of 100 connection’s metadata will be returned for each channel.

Disabling the presence feature

When the presence data is no longer required for a given channel you should disable it. You’ll need to know your private key.

Here is an example using the NodeJS SDK where the presence feature is disabled for the channel myChannel:

var ortcNodeclient = require('IbtRealTimeSJNode').IbtRealTimeSJNode;
var ortcClient = new ortcNodeclient();

ortcClient.disablePresence({
  applicationKey : '<ORTC_APPLICATION_KEY>',
  channel : 'myChannel', 
  privateKey : '<ORTC_PRIVATE_KEY>', 
  url : 'http://ortc-developers.realtime.co/server/2.1/',
  isCluster : true
},
function(error,result){
  if(error){
    console.log('Presence',error);  
  }else{
    console.log('Presence enable',result);        
  }
});
    

The same can be achieved using the Realtime PHP SDK:

<?php

	require('./ortc.php');

	// Generate a random string to use as token
	function generateRandomString($length = 10) {
	    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	    $charactersLength = strlen($characters);
	    $randomString = '';
	    for ($i = 0; $i < $length; $i++) {
	        $randomString .= $characters[rand(0, $charactersLength - 1)];
	    }
	    return $randomString;
	}

	$URL = 'https://ortc-developers.realtime.co/server/ssl/2.1';
	$AK = '<ORTC_APPLICATION_KEY>';
	$PK = '<ORTC_PRIVATE_KEY>';

	// Get a random string to use as Realtime token
	$TK = generateRandomString();
	$CH = 'myChannel';

	// Create the Realtime client instance
	$rt = new Realtime( $URL, $AK, $PK, $TK );

	// disable presence for the channel
	$result = $rt->disable_presence($CH);

?>

NOTE: If a channel has the presence feature activated and no presence calls are made for a period of 24 hours, the presence feature will be automatically disabled for that channel.

Configuring the client heartbeats

Normally a Realtime Messaging Server detects a client disconnect in milliseconds but in some situations, depending on the users’ browser, network and proxy/firewall, it can take longer (up to several minutes) and this can have a significant impact on the accuracy of the presence numbers for some applications (the server will report more subscribers). To solve this issue the JavaScript and ActionScript Pub/Sub API implement a client heartbeat.

A heartbeat is a small message sent by the client to the Realtime Messaging Server with a pre-defined interval (configured by the application). When the client heartbeat is activated the heartbeat interval default is 15 seconds.

When the Realtime Messaging Server detects that a given client isn’t sending the heartbeat for a specified period (the default is 3 lost heartbeats) it will consider that the user has disconnected and perform the normal disconnection operations (e.g. decrease the number of subscribers).

Depending on the requirements of your Realtime application you can specify different values for the heartbeat frequency and maximum allowed lost heartbeats (fails).

For details on how to use the client heartbeat feature please refer to the JavaScript and ActionScript SDK reference documentation at http://framework.realtime.co/messaging/#documentation.

Best practices

Every Realtime Messaging SDK implements the presence services methods (enable, disable and presence) so you can use the one that’s more suited for your applications’ stack. The only exception is the JavaScript SDK that doesn’t implement the enable and disable API calls since they would expose your private key.

This means that you should issue your enable and disable presence calls in a server side process context (e.g. using the Java or NodeJS SDK) and preferably using a SSL connection (replace /server/2.1 with /server/ssl/2.1 in your Realtime Messaging Cluster URL) to protect your application’s private key.

NOTE: If there isn’t a SDK for the language you require please refer to the RESTful Services documentation section.

Back to Webhooks - Next: Announcement channels

If you find this interesting please share: