Confirmed users
93
edits
No edit summary |
No edit summary |
||
| Line 7: | Line 7: | ||
== Purpose == | == Purpose == | ||
The SimplePush protocol is closely based on [http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/37474.pdf 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 | The SimplePush protocol is closely based on [http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/37474.pdf 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 signaling 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 == | == Definitions == | ||
| Line 16: | Line 18: | ||
;UserAgent | ;UserAgent | ||
A device or program that implements the client side of the Push Protocol. | A device or program that implements the client side of the Push Protocol. | ||
;UAID | |||
:A globally unique UserAgent ID. Used by the PushServer to associate channelIDs with a client. Stored by the UserAgent, but opaque to it. | |||
;Channel | ;Channel | ||
| Line 23: | Line 28: | ||
:Unique identifier for a Channel. Generated by UserAgent for a particular application. Opaque identifier for both UserAgent and PushServer | :Unique identifier for a Channel. Generated by UserAgent for a particular application. Opaque identifier for both UserAgent and PushServer | ||
; | ;Endpoint | ||
;A REST-ful HTTP URL uniquely associated to a channel. Requests to this URL should update the PushServer state for the channel. | |||
;Version | ;Version | ||
| Line 33: | Line 38: | ||
== Protocol Overview == | == Protocol Overview == | ||
The SimplePush protocol defines how UserAgents and PushServers communicate to ensure reliable delivery of the latest version of a channel from the PushServer to the UserAgent. | |||
The SimplePush communication channel is WebSockets, and the wire protocol is JSON, with messages defined below. All messages MUST use TLS (wss:// protocol for WebSockets). In addition, Endpoints generated by PushServer's MUST use HTTPS URLs. | |||
The PushServer should maintain a mapping of channelIDs and their versions and pushEndpoints. | |||
SimplePush is backed by a best effort delivery mechanism over WebSocket | |||
The protocol has some request-response driven actions, where the UserAgent MUST make requests, and the PushServer MAY respond. One message, <tt>notification</tt>, MAY be sent at any time by the PushServer. | |||
=== ChannelID, UAIDs and Endpoints === | |||
Since the UAID is the only unique identifier of a UserAgent, with no authentication information, it is important that UAIDs are not compromised. Only the UserAgent to which the UAID was assigned, and the PushServer, should know the UAID. An attacker can use a leaked UAID to pretend to be the UserAgent with that UAID. Although SimplePush does not transfer any private information, the attacker would still receive the notifications meant for the victim. If any party detects a compromise, they SHOULD reset the UAID. For this, the UserAgent may send a blank UAID and get a new one from the PushServer. Similarly the PushServer may send a new UAID during a handshake. | |||
ChannelIDs are also unique. It is RECOMMENDED that channelIDs be associated with a UAID, so that an attacker cannot receive notifications for a compromised channelID without also having accessed the UAID. | |||
It is RECOMMENDED that both UAID and channelIDs be UUIDv4 tokens. | |||
The format of the Endpoint is not specified by this protocol. There are two requirements that MUST be satisfied: | |||
* PushServers MUST use HTTPS, so the Endpoint URL will begin with "https://". | |||
* ChannelIDs and Endpoints MUST have a one-one mapping and Endpoints may not 'expire' while their channelID is still active. | |||
It is RECOMMENDED that Endpoints simply be a prefix followed by the channelID or some transformation of the channelID which is referentially transparent. PushServers SHOULD avoid exposing UAIDs in the Endpoints since they are sent to AppServers. | |||
== Messages == | == Messages == | ||
All messages are encoded as JSON. All messages MUST have the following fields: | |||
;messageType '''string''' | |||
:Defines the message type | |||
=== Handshake === | === Handshake === | ||
After the WebSocket is established, the UserAgent begins communication by | |||
sending a <tt>hello</tt> message. The hello message contains the UAID if the | |||
UserAgent has one. The UserAgent also transmits the channelIDs it knows so the | |||
server may synchronize its state. | |||
The server is MAY respect this UAID, but it is at liberty to ask the UserAgent | |||
to change its UAID in the response. | |||
If the UserAgent receives a new UAID, it MUST delete all existing channelIDs | |||
and their associated versions. It MAY then wake up all registered applications | |||
immediately or at a later date by sending them a <tt>push-register</tt> | |||
message. | |||
The handshake is considered ''complete'', once the UserAgent has received a reply. | |||
An UserAgent MUST transmit a <tt>hello</tt> message '''only once''' on its | |||
WebSocket. If the handshake is not completed in the first try, it MUST | |||
disconnect the WebSocket and begin a new connection. | |||
'''NOTE:''' Applications may request registrations or unregistrations from the | |||
UserAgent, before or when the handshake is in progress. The UserAgent MAY | |||
buffer these or report errors to the application. But it MUST NOT send these | |||
requests to the PushServer until the handshake is completed. | |||
==== UserAgent -> PushServer ==== | |||
; messageType = "hello" | |||
: Begin handshake | |||
; uaid string '''REQUIRED''' | |||
: If the UserAgent has a previously assigned UAID, it should send it. Otherwise send an empty string. | |||
; channelIDs list of strings '''REQUIRED''' | |||
: If the UserAgent has a list of channelIDs it wants to be notified of, it must pass these, otherwise an empty list. | |||
Extra fields: | |||
The UserAgent MAY pass any extra JSON data to the PushServer. This data may include information required to wake up the UserAgent out-of-band. The PushServer MAY ignore this data. | |||
===== Example ===== | |||
{ | |||
"messageType": "hello", | |||
"uaid": "1234567890", | |||
"channelIDs": ["r2d2", "c3po"] | |||
} | |||
==== PushServer -> UserAgent ==== | |||
PushServers MUST send only respond to a hello once. | |||
UserAgents MUST ignore multiple hello replies. | |||
; messageType = "hello" | |||
: Responses generally have the same messageType as the request | |||
; uaid string '''REQUIRED''' | |||
: If the UserAgent sent no UAID, generate a new one. If the UserAgent send a valid UAID and the PushServer is in sync with the UserAgent, send back the same UAID, otherwise send a new UAID. | |||
===== Example ===== | |||
{ | |||
messageType: “hello”, | |||
uaid: <if not provided by previous call, a new valid one will be generated> | |||
} | |||
=== Register === | === Register === | ||
| Line 48: | Line 144: | ||
== Acheiving reliable delivery == | == Acheiving reliable delivery == | ||
At any time, if the PushServer reaches an inconsistent condition, due to database failure, network failure, or any other reason, it MAY drop all state. It MUST then disconnect all active clients, forcing them to reconnect and begin a handshake to get synchronized. | |||
== Alternative communication == | |||
In environments or devices where maintaining an always alive WebSocket is difficult, UserAgents and PushServer's MAY implement alternative means to notify UserAgents about updates. This out of band notification SHOULD be restricted to request the UserAgent to establish the WebSocket. SimplePush state SHOULD NOT be transmitted out of band, since reliable delivery may not be guaranteed. | |||
API Push Client - Push Server | API Push Client - Push Server | ||