WebAPI/SimplePush/Protocol
This page describes the protocol used for communication by the PushServer and the UserAgent.
Status: Draft
Everything here applies to Version 1 of the protocol. Major versions may change underlying protocols, message formats and anything else.
Purpose
The SimplePush protocol is closely based on Thialfi: A Client Notification Service for Internet-Scale Applications and makes the same delivery guarantees, soft server state and client driven recovery. It is a signalling and not a data carrying system. The goal: To notify clients of changes to application server state in a reliable manner by ensuring that the client will always eventually learn of the latest version of an object for which it has expressed interest.
Definitions
- PushServer
A publicly accessible server that implements the server side of the Push Protocol and exposes an HTTP API for AppServer's to notify it.
- UserAgent
A device or program that implements the client side of the Push Protocol.
- Channel
- The flow of information from AppServer through PushServer to UserAgent.
- ChannelID
- Unique identifier for a Channel. Generated by UserAgent for a particular application. Opaque identifier for both UserAgent and PushServer
- UAID
- A globally unique UserAgent ID. Used by the PushServer to associate channelIDs with a client. Stored by the UserAgent, but opaque to it.
- Version
Monotonically increasing 64-bit integer describing the application state. This holds meaning as a primary key or similar only to the AppServer. The PushServer and UserAgent and App should use this only for detecting changes.
Protocol Overview
Describe in short how the protocol works
Messages
Handshake
Register
Unregister
Notification
Synchronization of server and client state
Acheiving reliable delivery
API Push Client - Push Server
This should be considered a translation to WebSockets of the API defined here - https://wiki.mozilla.org/WebAPI/SimplePush/ServerAPI Status/Error codes documented in that document apply here unless explicitly marked otherwise.
Push API endpoint for WebSocket connection is : wss://push.server.com/v1/
C->S:
{ messageType: "hello", uaid: "<a valid UAID>",
channelIDs: [channelID1, channelID2, …],
interface: {
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>"
},
protocol: <wakeup protocol. OPTIONAL. By default: UDP>
}
uaid can be null, then, a new uaid is created (see next)
S->C:
{ messageType: “hello”, status: xxx, <200, ...>, uaid: <if not provided by previous call, a new valid one will be generated> }
NOTE: All pending registration/unregistration requests stay on ‘hold’ until the client has transmitted new state and the server has concurred.
Recovery protocol
The client “hello” contains the “uaid” field. If the “uaid” field is known by the server, the server should check that the list of channelIDs sent by the client matches what it has. If there is even a single channelID that the server does not know about, it should generate a new UAID for the client, and drop all state about the current UAID. This will cause the client to generate new channelIDs by waking up all apps and having them register. This way apps get latest state since they contact their server.
If the server has ‘extra’ channelIDs associated with the UAID, it can simply delete them. Channel Registration:
A client channel registration request:
{ messageType: "register",
channelID: "<ChannelID>
}
The server response can be:
{ messageType: “register”, status: xxx, pushEndpoint: <pushendpoint>, channelID: <channelId> }
Channel Deletion:
{
messageType: "unregister", channelID: <channelId> }
The server response can be:
{
messageType: "unregister",
status: xxx,
channelID: <channelId> }
Channel Update:
Server -> Client { messageType: “notification”, updates: [{"channelID": "id", "version": "XXX"}, ...] }
Client -> Server { messageType: “ack”, updates: [{"channelID": channelID, “version”: xxx}, ...] } API Application Server - Notification Server
NOTIFICATION
https://server:port/notify/<hashed channelID> [Actually Opaque as far as anyone other than the push server is concerned]
Method PUT Payload:
version=<version>
April Discussion Below:
DESKTOP NOTIFICATION
https://server:port/notify/<hashed channelID>
Method PUT Payload:
body=<any text>[&ttl=<ttl>]
GROUPS MANAGEMENT [WIP]
CRUD API: C: POST https://server:port/groups Returns URL (pushEndpoint)
R: GET https://pushEndpoint Returns: [endPointURL1, endPointURL2, …]
U: PUT https://pushEndpoint url=endPointURLN&op=[ADD|DELETE] Returns: 200 OK or 404 No group found
D: DELETE https://pushEndpoint Removes the group Returns: 200 OK or 404 No group found
�
WAKEUP API [WIP]
This (WIP) API will be offered by the carriers in order to be able to wakeup handsets inside their own mobile networks.
Connection to this API will be protected with client certificates signed by the carrier so only trusted 3rd. party notification servers will be able to send datagrams to the handsets.
GET
mcc=<mcc>&mnc=<mnc>
RETURNS
200 OK (We’ve a wake up server in that network !)
404 Error (We don’t have a wake up server)
PUT
ip=<ip>&port=<port>&mcc=<mcc>&mnc=<mnc>
RETURNS
200 OK
�
Channel Update:
Server -> Client { messageType: “notification”, updates: [{"channelID": "id", "version": "XXX"}, ...] }
{
messageType: "desktopNotification",
updates: [{"channelID": "version", _internal_id: ..., "body": "body"}, ...]
}
Return Status codes
WIP: https://github.com/telefonicaid/notification_server/blob/mozAPI/src/common/constants.js nikhil: I think you’ll just want to use the ones from the mozilla spec that are required, like 404 and so on. Most of the other status codes are not required in my opinion.