q as a WebSocket client
WebSockets are a technology enabling two-way communication between a client and server over a single TCP connection, defined in RFC6455. Essentially an initial “handshake” HTTP request is sent from client to server, requesting an upgrade from HTTP to WebSocket protocol. The server responds with an Upgrade message, and communciation begins.
q has been able to act as a WebSocket client since v3.2, but the default usage is not the most intuitive, requiring the construction of a raw HTTP request string to be sent to the server e.g.
(In order to allow this, kdb+ automatically adds a number of header fields to
the HTTP request; Sec-WebSocket-Key
, Sec-WebSocket-Version
,
Sec-WebSocket-Extensions
, Upgrade
, Connection
)
In this example, an echo server is used which will simply echo whatever is sent
to it. Note that in addition to having to manually construct the query, the
handle returned is a positive int, while WebSockets require async messaging,
and therefore need a negative handle. Additionally, by default all messages
arriving over a WebSocket will be handled by .z.ws
, which is a little tricky
if you’re connecting to multiple servers from one q session.
To combat these annoyances, I built ws.q. This is a very simple library to wrap around the above functionality & provide WebSocket client functionality in a more convenient manner.
To set up ws.q
, clone the repo recursively e.g.
(The --recursive
flag is necessary to also pull reQ, an HTTP request library
which is used by ws.q
; this allows easily building the initial HTTP requests)
ws.q
allows for multiple callback functions, one per connection, set when
opening a WebSocket connection. Opening a connection is via .ws.open
, which
takes two arguments, the URL (as hsym, symbol or string) & the name of callback
function for this connection (as symbol). .ws.open
will return the negated
handle, ready for use in messaging. Taking the earlier example of the echo
server:
A table of open connections is found in .ws.w
:
As mentioned before, it is possible to open multiple concurrent WebSocket connetions:
Also present on the repo is an example WebSocket based feedhandler for the GDAX cryptocurrency exchange, which provides a WebSocket API. A number of other cryptocurrency exchanges provide WebSocket feeds, and I plan to add more example feedhandlers to this repo in time for some of them; keep an eye out for those if you’re interested! If there’s a particular feed you’d like to get implemented, or if you’d like help to integrate the GDAX fh into your kdb+ system, feel free to get in touch.
The repo also contains two files called wsu.q
& wschaintick.q
; these files
provide functionality for a chained TP which republished data from a regular
tickerplant over WebSockets in JSON format - this will be the subject of a
future post, but they should already be in a usable state if you need to stream
data from your TP over a WebSocket (e.g. perhaps to an HTML & JS dashboard,
rather than using some form of polling).