Real-time notifications

Overview

This section describes the aspects common to all the real-time notifications services of Cumulocity IoT.

Each service has his own subscription channel name format and URL which are described in section Notifications with REST interface documentation. The real-time notifications are available for:

The real-time notifications API enables responsive communication from Cumulocity IoT over restricted networks towards clients such as web browser and mobile devices. All clients subscribe to the so-called channels to receive messages. These channels are filled by Cumulocity IoT with the output of operations. In addition, particular system channels are used for the initial handshake with clients, subscription to channels, removal from channels and connection. The Bayeux protocol over HTTPS or WSS is used as communication mechanism.

Note that when using long-polling, all PUT/POST requests must contain the Accept header, otherwise an empty response body will be returned.

Info: The long-polling interface is designed as a mechanism for custom applications to poll infrequent events from Cumulocity IoT. The long-polling interface is not designed as a mechanism to stream large data volumes (>100kB/sec) or frequent data (>50 events/sec) out of Cumulocity IoT. The usage of long polling is not supported for such use cases.

Handshake

A real-time notifications client initiates connection negotiation by sending a message to the “/meta/handshake” channel. In response, the client receives a clientId which identifies a conversation and must be passed in every non-handshake request.

When using websockets, a property ‘ext’ containing an authentication object must also be sent. In case of basic authentication the “token” is used with base64 encoded credentials. In case of OAuth authentication the request must have the cookie with the authorization name, holding the access token. Further more the XSRF token must be forwarded as part of the handshake message.

{
  "ext": {
    "com.cumulocity.authn": {
      "token": "<base64 encoded credentials>",
      "tfa": "<tfa token>",
      "xsrfToken": "<xsrf token>",
    },
    "systemOfUnits": "<system of units>"
  }
}
Property Value
token Base 64 encoded credentials.
tfa Optional two factor authentication token.
xsrfToken Required for OAuth authentication.
systemOfUnits Optional system of units. Possible values are “imperial” or “metric”.

Request

Name Type Occurs Description
id string 1 ID of message, required to match response message.
channel string 1 The channel name as a URI, required value: “/meta/handshake”.
ext Object 1 Authentication object passed to handshake (only over websockets).
version string 1 Bayeux protocol version used by client.
minimumVersion string 0..1 Minimum server-side Bayeux protocol version required by client.
supportedConnectionTypes array 1 List of connection types supported by client.

Example request:

POST /cep/realtime
Host: ...
Authorization: Basic ...
Content-Length: ...
Content-Type: application/json
[
  {
    "channel": "/meta/handshake",
    "ext": {
      "com.cumulocity.authn": {
        "token": "<base64 encoded credentials>"
      }
    }
    "version": "1.0",
    "mininumVersion": "1.0beta",
    "supportedConnectionTypes": ["websocket","long-polling"]
  }
]

Response

Name Type Occurs Description
id string 1 ID of message passed in request message.
channel string 1 The channel name as a URI, required value: “/meta/handshake”.
version string 0..1 Bayeux protocol version used by server.
minimumVersion string 0..1 Minimum client-side Bayeux protocol version required by server.
supportedConnectionTypes array 0..1 Connection types supported by both client and server (i.e., intersection between client and server options).
clientId string 0..1 Unique client ID generated by server.
successful boolean 1 Result of handshake.
error string 0..1 Handshake failure reason.

Example of successful response:

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "channel": "/meta/handshake",
    "version": "1.0",
    "minimumVersion": "1.0",
    "supportedConnectionTypes": ["websocket"],
    "clientId": "Un1q31d3nt1f13r",
    "successful": true
  }
]

Example of failed response:

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "channel": "/meta/handshake",
    "successful": false,
    "error":"403::Handshake denied"
  }
]

Subscribe

A notification client can send subscribe messages and specify there the desired channel to receive output messages from Cumulocity IoT server. The client will receive the messages in succeeding connect requests.

The format of channels names is different according to the REST API in which the real-time notification service is used. See Device control for more details.

Request

Name Type Occurs Description
id string 1 ID of message, required to match response message.
channel string 1 The channel name as a URI, required value: “/meta/subscribe”
clientId string 1 Unique ID of client received during handshake.
subscription string 1 Name of channel to subscribe to.

Example Request:

POST /cep/realtime
Host: ...
Authorization: Basic ...
Content-Length: ...
Content-Type: application/json
[
  {
    "channel": "/meta/subscribe",
    "clientId": "Un1q31d3nt1f13r",
    "subscription": "/alarms/<Device ID>"
  }
]

Response

Name Type Occurs Description
id string 1 ID of message passed in request message.
channel string 1 The channel name as a URI, required value: “/meta/subscribe”.
clientId string 1 Unique ID of client.
subscription string 1 Name of channel.
successful boolean 1 Result of subscription.
error string 0..1 Subscription failure reason.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "channel": "/meta/subscribe",
    "clientId": "Un1q31d3nt1f13r",
    "subscription": "/alarms/<Device ID>",
    "successful": true,
    "error": ""
  }
]

Unsubscribe

To stop receiving notifications from a channel, send a message to /meta/unsubscribe supplying the proper channel name in the same format as used during subscription.

Request

Name Type Occurs Description
id string 1 ID of message, required to match response message.
channel string 1 The channel name as a URI, required value: “/meta/unsubscribe”.
clientId string 1 Unique client ID received during handshake.
subscription string 1 Name of channel.

Example Request:

POST /cep/realtime
Host: ...
Authorization: Basic ...
Content-Length: ...
Content-Type: application/json
[
  {
    "channel": "/meta/unsubscribe",
    "clientId": "Un1q31d3nt1f13r",
    "subscription": "/alarms/<Device ID>"
  }
]

Response

Name Type Occurs Description
id string 1 ID of message passed in request message.
channel string 1 The channel name as a URI, required value: “/meta/unsubscribe”.
clientId string 1 Unique ID of client.
subscription string 1 Name of subscribed channel.
successful boolean 1 Result of unsubscription.
error string 0..1 Unsubscription failure reason.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "channel": "/meta/unsubscribe",
    "clientId": "Un1q31d3nt1f13r",
    "subscription": "/alarms/<Device ID>",
    "successful": true,
    "error": ""
  }
]

Connect

After a Bayeux client has discovered the server’s capabilities with a handshake exchange and subscribed to the desired channels, a connection is established by sending a message to the /meta/connect channel. This message may be transported over any of the transports returned by the server in the handshake response. Requests to the connect channel must be immediately repeated after every response to receive the next batch of notifications.

Request

Name Type Occurs Description
id string 0..1 ID of message, required to match response message.
channel string 1 The channel name as a URI, required value: “/meta/connect”.
clientId string 1 Unique ID of client received during handshake.
connectionType string 1 Selected connection type.
advice Object 0..1 Configuration parameters for current connect message.

Advice

Name Type Occurs Description
timeout int 0..1 Interval between sending of connect message and response from server. Overrides server default settings for current request-response conversation.
interval int 0..1 Period above which server will close session, if not received next connect message from client. Overrides server default settings for current request-response conversation.

Example Request :

POST /cep/realtime
Host: ...
Authorization: Basic ...
Content-Length: ...
Content-Type: application/json
[
  {
    "channel": "/meta/connect",
    "clientId": "Un1q31d3nt1f13r",
    "connectionType": "long-polling",
    "advice":{"timeout":1200000,"interval":30000}
  }
]

Response

Name Type Occurs Description
id string 0..1 ID of message passed in request message.
channel string 1 The channel name as a URI.
clientId string 1 Unique ID of client.
successful boolean 1 Result of connect.
data array 1 List of notifications from channel.
error string 0..1 Connect failure reason.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json
[
    {
        "channel": "/alarms/208",
        "id": "79",
        "data": {
            "realtimeAction": "UPDATE",
            "data": {
                "severity": "MAJOR",
                "creationTime": "2019-10-29T13:10:21.297Z",
                "count": 2,
                "history": {
                    "auditRecords": [],
                    "self": "https://[..]/audit/auditRecords"
                },
                "source": {
                    "self": "https://[..]/inventory/managedObjects/208",
                    "id": "208"
                },
                "type": "c8y_Application__BackOff",
                "firstOccurrenceTime": "2019-10-29T13:10:21.000Z",
                "self": "https://[..]/alarm/alarms/327",
                "time": "2019-10-29T13:10:36.000Z",
                "id": "327",
                "text": "Back-off restarting failed container",
                "status": "ACTIVE",
                "c8y_Application__Metadata": {
                    "owner": "management",
                    "tenant": "management"
                }
            }
        }
    },
    {
        "advice": {
            "interval": 0,
            "timeout": 5400000,
            "reconnect": "retry"
        },
        "channel": "/meta/connect",
        "successful": true
    }
]

Disconnect

To stop receiving notifications from all channels and close the conversation, send a message to the /meta/disconnect channel.

Request

Name Type Occurs Description
id string 0..1 ID of message, required to match response message.
channel string 1 The channel name as a URI, required value: “/meta/disconnect”.
clientId string 1 Unique ID of client received during handshake.

Example response :

POST /cep/realtime
Host: ...
Authorization: Basic ...
Content-Length: ...
Content-Type: application/json
[
  {
    "channel": "/meta/disconnect",
    "clientId": "Un1q31d3nt1f13r",
  }
]

Response

Name Type Occurs Description
id string 0..1 ID of message passed in request message.
channel string 1 The channel name as a URI, required value: “/meta/disconnect”.
successful boolean 1 Result of disconnect operation.
clientId string 1 Unique ID of client received during handshake.
error string 0..1 Disconnect failure reason.

Example response :

HTTP/1.1 200 OK
Content-Type: application/json
[
  {
    "channel": "/meta/disconnect",
    "clientId": "Un1q31d3nt1f13r",
    "successful": true
  }
]