API between the User Agent and the Notification Server

With this API the client device is able to register his applications and itself into the selected notification server.

This API isn't yet standarised, anyway the one explained here is an on working proposal.

The UA-NS API is divided in two transport protocols:

HTTP API

This channel only offers one method to get server information.

about

This method responds an HTML page with general information about the running server like number of connections, number of process running...

status

This method is used to check if the server is available or not. Is designed to be used by load balancers when the server is under maintance.

The server will responde 200 (OK) if the server is enabled or 503 (Under Maintance).

To set the server into maintance mode (tell the load balancer that the server is not available) is needed to send a SIGUSR1 signal to the proccess:

      
      kill -SIGUSR1 <pid>
      
    

To set the server into normal mode (tell the load balancer that the server is available) is needed to send a SIGUSR2 signal to the proccess:

      
      kill -SIGUSR2 <pid>
      
    

WebSocket API

Through this channel the device will register itself, his applications, and also will be used to deliver PUSH notifications

The websocket API supports multiple subprotocols identified each one with it's name:

  • push-notification

    Simple protocol defined by Mozilla and Telefonica and described here: [https://wiki.mozilla.org/WebAPI/SimplePush/Protocol] .

  • push-notification-binary

    Binary version of the push-notification protocol

  • push-extended-notification

    Telefonica extended solution which provides more functionalities

WebSocket: push-notification

Also know as "Simple push protocol" and defined by Mozilla and Telefonica.

This protocol is based in the Thialfi protocol . described by Google.

Also you can read more about this protocol in the Mozilla Wiki: [https://wiki.mozilla.org/WebAPI/SimplePush/Protocol] .

In order to use this subprotocol, the "push-notification" string shall be sent into the websocket handsake headers.

All methods sent through this channel will have the same JSON structure:

  
  {
    messageType: "<type of message>",
    ... other data ...
  }
  
  

In which messageType defines one of these commands:

hello

With this method the device is able to register itself.

The device is responsible to give the server a valid UAID. If the provided UAID is not valid or is "null", the server will respond with a valid one.

In next connections the UAID given by the server SHALL be used.

When a device is registering to a notification server, it SHALL send his own valid UAID and also the device can send additional information that can be used to optimize the way the messages will be delivered to this device.

If it's not the first connection, the device can send a list of registered channels in order to syncronize client and server data. This mechanism allows a way to recover channels after a server crash.

    
    {
      messageType: "hello",
      uaid: "<a valid UAToken>",
      channelIDs: [<a list of channels to sync [OPTIONAL]>],
      wakeup_hostport: {
        ip: "<current device IP address>",
        port: "<TCP or UDP port in which the device is waiting for wake up notifications>"
      },
      mobilenetwork: {
        mcc: "<Mobile Country Code>",
        mnc: "<Mobile Network Code>"
      }
    }
    
    

The wakeup_hostport and mobilenetwork optional data will be used by the server to identify if it has the required infrastructure into the user's mobile network in order to send wakeup messages to the IP and port indicated in the wakeup_hostport data so it's able to close the WebSocket channel to reduce signalling and battery consume.

The channelIDs array is sent by the client in order to synchronize server and client.

When the server receives a new hello message and the UAID provided by the client is a valid one (in other words, is the same returned to the client) the channelIDs list will be used to syncronize the server information with the client one.

For example, after a server crash, all client channels will be recovered with this simple method.

Another example, if the client uninstalled an app when the handset was offline, next time it connects will send tne channel list with one less, so the server will unregister this channel.

The server response can be one of these:

      
      {
        messageType: "hello",
        uaid: "<a valid UAID>",
        status: 200
      }
      
      

if it's connected through a permanent websocket, or:

      
      {
        messageType: "hello",
        uaid: "<a valid UAID>",
        status: 201
      }
      
      

if it's connected to a wakeup channel (UDP).

Note

This hello response differenciation is pending to change in order to use Websocket close status: on this Github Pull Request .

      
      {
        messageType: "hello",
        status: 4xx,
        reason: "<any reason>"
      }
      
      

on any error case, like:

  • 460: Error registering UAID

This method is also used to anounce a new IP address or a network change.

register

This method is used to register push channels. Each application can register as many channels as it wants. Each channel maintains an independent counter about the last version of the channel.

This shall be send to the notification server after a valid UA registration.

Normally, this method will be used each time an application requires a new channel to receive Thialfi like notifications. A new endpoint URL will be delivered (through the WA-UA API).

No data is required at application level, only the UA client is responsible to generate a unique channelID for the handset. The channelID can be the same in different devices since the UAID will be used in the endpoint URL hash.

    
    {
      messageType: "register",
      channelID: "<a new channelID>"
    }
    
    

The server response can be:

      
      {
        messageType: "register",
        status: 200,
        pushEndpoint: "<publicURL required to send notifications>",
        channelID: "<the channelID>"
      }
      
      

      
      {
        messageType: "register",
        status: 4xx,
        reason: "<any reason>"
      }
      
      

on any error case, like:

  • 457: Not valid channelID
  • 408: Server is not ready yet

The device service should redirect the received URL to the correct application.

unregister

This method is used to unregister a push channel.

This shall be send to the notification server after a valid UA registration.

    
    {
      messageType: "unregister",
      channelID: "<a new channelID>"
    }
    
    

The server response can be:

      
      {
        messageType: "register",
        channelID: "<a new channelID>"
        status: 202
      }
      
      

      
      {
        messageType: "register",
        status: 4xx,
        reason: "<any reason>"
      }
      
      

on any error case, like:

  • 408: Server is not ready yet

notification

This message will be used by the server to inform about new notification to the device.

All recieved notification(s) will have this structure:

    
    {
      messageType: "notification",
      updates: [
        {
          channelID: "<channelID>",
          version: "<versionNumber>"
        },
        {
          channelID: "<channelID>",
          version: "<versionNumber>"
        },
        ...
      ]
    }
    
    

On updates list, is returned all the list of pending notifications (last version of each channel)

desktop-notification

This message will be used by the server to inform about new desktop notification to the device.

These notifications SHOULD be showed into the device notification area.

All recieved notification(s) will have this structure:

    
    {
      messageType: "desktopNotification",
      updates: [
        {
          channelID: "<channelID>",
          _internal_id: "<id>",
          body: "<some text>"
        },
        {
          channelID: "<channelID>",
          _internal_id: "<id>",
          body: "<some text>"
        },
        ...
      ]
    }
    
    

On updates list, is returned all the list of pending notifications (last version of each channel)

ack

For each received notification through notification, the server SHOULD be notified in order to free resources related to this notifications.

This message is used to acknoledge the message reception.

      
      {
        messageType: "ack",
        updates: [
          {
            channelID: "<channelID>",
            version: "<versionNumber>"
          },
          {
            channelID: "<channelID>",
            version: "<versionNumber>"
          },
          ...
        ]
      }
      
      
Keep-alive algorithm

If it's needed a way to maintaint the socket open along time, a PING-PONG mechanism is also implemented.

The client sents an empty JSON object "{}" and the server will respond another empty object "{}" and/or a notification response (if pending notifications).

Wakeup websocket close

As explained before, when the client informs about the mobile network is in and the server has the required infrastructure in that mobile network, the websocket will be closed by the server after a predefined inactivity time (10 seconds).

When this timer fires, the websocket will be closed with the 4774 status code.

[WebSocket protocol] .