Xtomp handbook

WebSockets

xtomp directly supports websockets.

TL;DR

STOMP is a text oriented messaging protocool that takes everything thats good about the Web and HTTP and applies it to messaging.

WebSockets is a binary message passing protocol that ignores everything good about the Web and HTTP and adds some really crazy complexity just for laughs. I suspect Google are trying to make server-side web technologies complicated to out-tech their competition, but I digress.

WebSockets is ubiquitous and xtomp has support for this protocol out of the box.

This makes it possible to create STOMP clients in a browser.

Configuration

If you enable

websockets on;

in xtomp.conf xtomp will handle both STOMP protocol and websockets protocol on the same port.

If you dont want to accept STOMP protocol from t'interwebs, put an nginx proxy in front.

The nginx configuration for a websockets proxy is as follows

location = /xtomp {
    proxy_pass http://localhost:61613/xtomp;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Connecting

Connect to xtomp with

var webSocket = new WebSocket("ws://myhost:61613/xtomp", "stomp");

The final argument is the sub-protocol; this MUST be "stomp".
The path /xtomp is arbitrary, if using nginx it must match the location in the proxy's location.

Once connected you are still expected to use STOMP connection protocol so as a minimum handshake you should call

webSocket.onopen = function (event) {
    webSocket.send("CONNECT\n\n\0");
}

As with xtomp's implementation of STOMP you MUST wait for a response to the CONNECT before sending SUBSCRIBE or SEND frames.

When xtomp sends a message to the websockets client the whole STOMP frame is delivered in a single message.

webSocket.onmessage = function (event) {
    let frame = stompFrame.parseStompMessage(event.data);
};

stompFrame.parseStompMessage() is provided by the stomp-frame module available from npm

In the above example xtomp port is 61613, so it communicates direct to xtomp, its probably better to proxy via nginx on the nginx port (80 or 443) Serving pages on 80 and WebSockets on 61613 requires cross origin settings in xtomp.conf.

Framing

Each STOMP message should be sent in a singe WebSockets frame. i.e. when sending a STOMP message via WebSockets send the whole message including the \0 terminator in a single call to send().

If you dont send the \0 terminator xtomp will wait until you do, and generate an error if you never do. Future versions may return errors immediatly.

Explanation for this requirement follows...

Despite its name websocket is not a socket level protocol, or a streaming protocol, text or binary messages are wrapped in binary packets similar to IP. The "stomp" subprotocol expects text to be sent exactly according to the STOMP spec, which does not specify anything about framing.
Since STOMP studiously avoids getting involved in the trasport (good decision) its possible to run STOMP over websockets relativly painlesly.

xtomp sends its STOMP frames as multiple websockets packets that make up a single message, so the browser JavaScript will only be delivered whole STOMP frames. i.e. the onmessage callback will always receive a whole STOMP message.

This makes writing browser code easier, but makes it impossible to process received messages as streams. It is possible to send large STOMP frames chunks over websockets.

Ideally message size should be kept down, since its not possible to parse STOMP data as a stream over websockets.



by teknopaul