The Ably realtime service supports client connections over multiple transports. The Comet transport is a fallback transport for environments that are unable to support WebSockets (eg older browser versions) or for environments for which intervening proxies do not support WebSockets.
In the Comet protocol, all request and response bodies contain an array of one or more protocol messages. In the binary protocol this is a standard binary MessagePack encoding. In the text (JSON) protocol request and response bodies are simply JSON-encoded arrays containing the Protocol Message content, again either in binary (MessagePack) or text (JSON) encoding.
Comet exchanges messages with the service using two primary mechanisms:
- operations that are initiated by the client – publishing messages, and making attach or detach requests – are performed by making a
POSTrequest to a /send endpoint, with the result of that particular operation being returned in the HTTP response.
- operations that are initiated by the service – notably delivery of published messages to the client – are performed by responding to a long-running HTTP
GETrequest to a /recv endpoint. As soon as such a request completes, the client initiates a new recv request. The service responds to recv requests periodically, even if there is no message to send, with a
The service ensures that responses do not occur out of order in cases that send and recv requests are made on the same socket.
There is at most one request of each type – send and recv – pending at any time. For this reason, there will be periods in which there is no pending recv request at the service (after having responded to one request and before the new request is received). Messages destined for the client that arrive during that time are queued until the next inbound recv request, and sent as a response as soon as the recv is received. The response body is therefore an array of Protocol Messages in order to support this. Similarly the send request body is an array of messages, to permit queueing of messages at the client whilst waiting for the response from the previous send request.
The service exposes a /connect endpoint for transport establishment and a /close endpoint for connection disposal.
The Comet protocol operates most efficiently when TCP sessions are persistent and serial requests for a given connection are handled by the same frontend instance. The Ably load balancer for the Comet host therefore implements sticky sessions based on a session cookie in the initial connect response. Environments that are capable of supporting third party cookies should enable this for the Ably Comet host.
This section defines details of the protocol in the sections that follow:
Comet operations are performed over HTTP or HTTPS to the Ably REST host (rest.ably.io or one of the fallback hosts).
The client library must allow the client to specify a non-default host or environment, at least to be able to connect to the standbox environment at sandbox-rest.ably.io.
Certain apps may be configured to require TLS connections and will reject non-TLS connections.
All requests include an Authorization header with the applicable auth params.
POST requests that contain one or more Protocol Messages in the request body are either JSON-encoded arrays with an “application/json” Content-Type, or binary-encoded MessagePack arrays with “application/x-msgpack” Content-Type.
All requests that expect one or more Protocol Messages in the response body must specify an Accept header with either “application/json” or “application/x-msgpack” depending on whether or not the transport is operating in text or binary mode. Again, response bodies for success responses will be JSON arrays of Protocol Messages or binary encoded MessagePack arrays as appropriate.
All error responses are made with a status code that reflects the nature of the error and an Error response body.
A Comet transport is initiated by making a
GET request with the path /comet/connect.
The URI must include a valid set of connection params to specify the recovery mode. The connection recovery mode is one of “clean”, “resume” or “recover”. Clean mode is the default, and is assumed if no connection params are specified.
Resume or recover mode are specified by including a
recover param respectively. In each case the value of that param is the private connectionKey string of the connection that is being recovered.
Resume and recover mode also require a
connection_serial param to be specified whose value is the (decimal representation of the) serial number of the last message received.
The response to the connect request is a single Protocol Message; the action will be
CONNECTED in the success case and
ERROR in the failure case. The error member, if present, indicates the failure condition (which can include non-fatal conditions in the
CONNECTED case). In each case the library must report that error information to the client.
CONNECTED response will include a connectionId member which is the connection path. This must be used in all subsequent requests associated with that connection.
Send operations are made by making either
POST requests to the path:
POST requests are formed with an encoded set of Protocol Messages in the request body.
GET send requests are only supported for very limited environments that are unable to support
POST, and the use of
GET for send operations is not recommended.
send operations are used for:
DETACH: the response contains the relevant error or the
PRESENCE: the response is either an empty response with a success status code, signifying success, or an error response with applicable status code and Error response body.
Recv operations are made by making a
GET request to the path:
These requests are expected to remain open until there is a
PRESENCE response, or a
At any time after a successful connection, the service may initiate termination of the connection by sending a error response (with appropriate status code and Error response body) to a pending recv.; this might occur for example if the credentials have been revoked, or the account has breached a hard connection limit. If a connection error message is received, the error information must be passed to the client as the failure reason.
Disconnection of the transport, in the case that the client wishes to be able to recover connection state, simply requires the client to cancel any pending recv request and issue no further requests.
Closing the connection, resulting in disposal of connection state, is achieved by sending a
GET request to the path:
Abnormal termination for whatever reason (a transition to the failed connection state) again just requires that any pending requests are cancelled.