Skip to content

Advanced features

Receipts & Suspension

The STOMP protocol supports RECEIPT frames, allowing the client to know when the server has received a frame. This only happens if a receipt header is set on the client frame.

If auto-receipt is enabled, a receipt header is automatically generated and added to all client frames supporting the mechanism, and for which a receipt header is not already present. If auto-receipt is not enabled, a receipt header may still be provided manually in the parameters of some overloads.

When a receipt header is present (automatically added or manually provided), the method that is used to send the frame suspends until the corresponding RECEIPT frame is received from the server. If no RECEIPT frame is received from the server in the configured time limit, a LostReceiptException is thrown.

If no receipt is provided and auto-receipt is disabled, the method used to send the frame doesn't wait for a RECEIPT frame and never throws LostReceiptException. Instead, it returns immediately after the underlying web socket implementation is done sending the frame.

Heart beats

When configured, heart beats can be used as a keep-alive to detect if the connection is lost. The heartBeat property should be used to configure heart beats in the StompClient.

Note that the heart beats for the STOMP session are negotiated with the server. The actual heart beats are defined by the CONNECTED frame received from the server as a result of the negotiation, and may differ from the StompClient configuration. The negotiation behaviour is defined by the specification.

Sending and checking heart beats is automatically handled by StompSession implementations, depending on the result of the negotiation with the server. If expected heart beats are not received in time, a MissingHeartBeatException is thrown and fails active subscriptions.

Graceful disconnect

The graceful disconnect (or graceful shutdown) is a disconnection procedure defined by the STOMP specification to make sure the server gets all the frames before dropping the connection.

If enabled in the config, when disconnecting from the server, the client first sends a DISCONNECT frame with a receipt header, and then waits for a RECEIPT frame before closing the connection.

If this graceful disconnect is disabled, then calling StompSession.disconnect() immediately closes the web socket connection. In this case, there is no guarantee that the server received all previous messages.

Using custom headers in the web socket handshake

Not supported in browsers

The browser's WebSocket API does not support custom headers in the handshake (see this open issue in the web socket standard repo). Because of this, Krossbow cannot support this feature for the JS browser platform. However, the JS web socket client adapter is designed in a way that allows other implementations to support it, such as a Node.js implementation.

Some servers or connection flows may require extra HTTP headers in the web socket handshake. The StompClient.connect() function doesn't support such headers out of the box, but this function is essentially just a shorthand for connecting at the web socket level, and then connecting at the STOMP level.

In fact, we technically don't need to create and use a StompClient at all in order to use STOMP with Krossbow. Krossbow provides a WebSocketConnection.stomp() extension function that establishes a STOMP connection from an existing web socket connection.

We can leverage this to customize the web socket connection at will before connecting at STOMP level. For example:

val webSocketClient = WebSocketClient.builtIn() // or another web socket client

// connect at web socket level with custom headers
val wsSession = webSocketClient.connect(url, headers = mapOf("Custom-Header" to "custom-value"))

val config = StompConfig().apply {
    // here you can set up whatever config you would have done in the StompClient { ... } block
}
// connect at STOMP level on this open web socket, using the above config
val stompSession = wsSession.stomp(config)