JSON Messaging Over HTTP
JSON Messaging is a set of conventions for using JSON to encode a bidirectional object-to-object message connection between two machines. The underlying transport abstraction assumed is that of TCP: a simple, persistent, bidirectional communications pipe. However, various practicalities, notably the desire to enable unmodified web browsers to act as clients, dictate that we be able to use HTTP as the underlying transport layer.
Since HTTP is stateless and sessionless, an additional transport protocol is required when the message transport medium is HTTP. This protocol uses special URLs and additional JSON encoding within the HTTP request and reply bodies to efficiently synthesize a sessionful, symmetric, bidirectional, asynchronous message channel out of an ongoing series of transient, asymmetric, synchronous, RPC-style HTTP requests. This document describes the details of this transport protocol.
Client Connection
GET ROOT/connector
GET ROOT/connect/RANDOMSTUFF
This initiates a new application-level session.
ROOTis the configured URL root. This is typically something likehttp://foonbat.example.com:8001/tst, where the protocol, host domain, host port, and URI prefix are all part of the server's configuration.RANDOMSTUFFis any random text the browser wishes to suffix so as to make the URL unique, in the interest of defeating misconfigured caching. This text is ignored by the server.
The HTTP reply body contains the JSON:
{
sessionid: SESSIONID
}
where:
sessionidis the server-assigned browser session ID. This is an unguessable token assigned by the server to the connection. It will be used in the construction of further request URLs for operations associated with the session.SESSIONIDis a string literal.
Server to Client Messaging
GET ROOT/select/SESSIONID/SSEQNUM
This is a poll for messages from the server to the client. (Actually, it
is more like Unix's select() combined with read()).
SESSIONIDis the session ID, assigned by the server in response to the/connect/request.SSEQNUMis a sequence number that enables the client to cope with message ordering in an asynchronous environment. The server assigns these in sequential, increasing order.SSEQNUMshould be the value of theseqnumproperty that was returned in the reply to the most recent previous/select/request, or1if there have not yet been any/select/requests sent for this session.
The HTTP reply body contains the JSON:
{
msgs: [MSG, MSG, ...],
seqnum: NEWSSEQNUM
}
where:
msgsis an array of zero or more JSON message objects. If the server has no messages to report, it may, at its option, omit themsgsproperty entirely, rather than sending a zero-length array. EachMSGis a normal JSON message object.seqnumis the sequence number to use for the next/select/request associated with this session.NEWSSEQNUMis a string literal.
Client to Server Messaging
POST ROOT/xmit/SESSIONID/XSEQNUM
This is a delivery of one or more messages from the client to the server.
The messages are transmitted, in the form of sequential JSON message literals, as the HTTP request body.
XSEQNUMis a sequence number that enables the server to deal with dropped, repeated, or out-of-order messages. The server assigns these in increasing order.XSEQNUMshould be the value of theseqnumproperty that was returned in the reply to the most recent previous/xmit/request, or1if there have not yet been any/xmit/requests sent for this session.
The HTTP reply body contains the JSON:
{
seqnum: NEWXSEQNUM,
}
where:
seqnumis the sequence number to use for the next/xmit/request associated with this session.NEWXSEQNUMis a string literal.
Client Disconnection
GET ROOT/disconnect/SESSIONID
This terminates an application level session.
The HTTP reply body contains the JSON:
{
}
Errors
Sometimes the browser may become confused (due to browser bugs, for example) about the appropriate URL to use for sending or receiving messages. In such a case, it may send an inappropriate HTTP request to the server that will contain an invalid sequence number or session ID.
In the case of such an error, the server will respond with the reply:
{
error: ERRORNAME
}
where:
erroris a string that depends on the nature of the error. It will be one of the strings"sessionIDError"or"sequenceError", depending on which part of the requested URL was wrong.
