WebSockets

RdbHost.com now supports websockets. Your client app can connect to the RdbHost server via a durable websocket as an alternative to https connections. This page is primarily interesting to those of you not using the provided interface modules, as those will automatically use websockets when appropriate.

The Python and JavaScript modules have not been adapted yet, but that is coming.

Overview

Websockets are a feature of html5, and allow a client to establish one connection for the session, and send all requests through that connection. The speed difference is substantial, as the connection does not have to be rebuilt for each request. Also, you save a few tens of bytes of authentication data per request, as the websocket channel can 'hold' the authenticated state.

Aside from the speed benefit, the benefit of websockets is the server can send data to the client asynchronously, without waiting for a request. This useful for chat applications, for example, or more generally for keeping the client data current when server data changes.

At RdbHost, the asynchronous behavior is based on the use of PostgreSQL's NOTIFY statement.

How To

To connect to the server websocket, use the path '/wsdb/<rolename>'. An example url would be:

wss://www.rdbhost.com/wsdb/s0000000004

If your app uses multiple roles, make a separate connection for each.

To request data, use the same JSON format that works as the body on regular https requests. Send the JSON body over the established websocket connection.

The data request is asynchronous: you send a request, and sometime later the response comes back. Responses to other queries, or notifications, can arrive in between. You should add some unique identifier to your query, so that you can associate the response data with the request. Try something like:

SELECT 'unique-id001';
SELECT * FROM important_table;

The first item of the recordsets attribute would contain the value 'unique-id001', and you can match it up with the request. If you use our provided modules, this correlating of responses to requests is done for you.

Asynchronous Messaging

To send a message to other websocket-connected clients, use the PostgreSQL LISTEN and NOTIFY statements.

For example, submit this aggregate query:

LISTEN "advice";
NOTIFY "advice", 'do not visit Seattle without an umbrella';
COMMIT; BEGIN;

There is an implied 'BEGIN' before the query, and an implied 'COMMIT' at the end, so this is effectively two transactions, the second one empty. That it is two transactions is important because PostgreSQL only processes a NOTIFY at the end of a transaction, and the second transaction is there to capture the NOTIFY message from the first.

The above query accomplishes two things: it sends the message to all clients registered for the channel 'advice', and it registers your client on that channel.

To just register the client, send an empty NOTIFY:

LISTEN "advice"; NOTIFY "advice";
COMMIT; BEGIN;

The asynchronous messages, when they arrive, have a status value of ['notify', 'OK']. For example:

{
    status: ["notify", "OK"],
    payload: "do not visit Seattle without an umbrella",
    channel: "advice"
}

This status value allows you to distinguish the asynchronous messages from query results, which will have status values starting with 'complete' or 'incomplete'.

We use NOTIFY to enable a 'side-channel', separate from query results. You can embed a NOTIFY into any INSERT or UPDATE query to notify all registered clients that the database has changed. The client app can then respond with a query to get the changed data. The NOTIFY does not interfere with the normal results delivery to the requester.