Krossbow STOMP and WebSocket Client

repository·main·Indexed 42 days ago

https://github.com/joffrey-bion/krossbow

A Kotlin multiplatform STOMP 1.2 client with a coroutine-based API. It supports multiple WebSocket transport adapters including Ktor, OkHttp, Spring, and SockJS, and provides various serialization options via Kotlinx Serialization, Jackson, and Moshi.

Tokens
15.5K
Snippets
47
Records
79
Agent score
52%

What's inside Krossbow

  1. Overview of Krossbow STOMP client

    main

    Krossbow is a Kotlin multiplatform STOMP 1.2 client designed with a coroutine-based API. It allows developers to interact with STOMP brokers using Kotlin coroutines across different platforms.

    Krossbow is highly extensible through adapters, allowing you to use various underlying WebSocket clients such as:

    • OkHttp
    • Ktor
    • Spring
    • SockJS

    It also includes a built-in, zero-dependency WebSocket implementation for certain platforms.

  2. Overview of Krossbow STOMP and WebSocket client

    main

    Krossbow is a Kotlin multiplatform STOMP 1.2 client featuring a coroutine-based API. It is built on a web socket client abstraction and can be used either as a STOMP client or as a multiplatform web socket client without the STOMP protocol.

    Key STOMP features include:

    • Full STOMP 1.2 specification support (including ACK/NACK and transactions).
    • Support for text and binary bodies.
    • Receipts (waiting for RECEIPT frames based on receipt headers).
    • Heartbeats (keep-alive).
    • Custom headers.
    • Auto-receipts (automatic addition of receipt headers to prevent frame loss).
    • Built-in body conversions (via Kotlinx Serialization or Jackson).
    • Custom body converter hooks.
    • Automatic content-length header for sent frames.
  3. Use Flow adapters to bridge listener-based WebSocket APIs

    main

    The krossbow-websocket-core module provides helper classes to adapt traditional listener-based WebSocket APIs to Krossbow's Flow-based API.

    WebSocketListenerFlowAdapter

    Use this adapter when your underlying WebSocket API supports suspend callbacks. It handles partial message assembly automatically and provides backpressure support by suspending the callback caller.

    UnboundedWsListenerFlowAdapter

    Use this adapter for APIs that do not support backpressure (such as the JavaScript browser WebSocket API). The callback functions are not suspend and return immediately, adding new messages to an unbounded queue.

  4. Perform a graceful STOMP disconnect

    main

    A graceful disconnect ensures the server receives all pending frames before the connection is dropped, following the STOMP specification.

    • Enabled: If graceful-disconnect is enabled in your configuration, calling StompSession.disconnect() will first send a DISCONNECT frame with a receipt header and wait for a RECEIPT frame from the server before closing the connection.
    • Disabled (Default): If disabled, calling StompSession.disconnect() immediately closes the underlying web socket connection. In this mode, there is no guarantee that the server has processed all previously sent messages.
  5. Using body conversions for Kotlin objects

    main

    While basic usage handles text, Krossbow supports automatic conversion of Kotlin objects to and from STOMP frame bodies. You can configure these conversions using several libraries:

    • Kotlinx Serialization: Recommended for multiplatform projects.
    • Jackson: For JVM-only projects.
    • Moshi: For JVM-only projects.
    • Custom conversions: For specialized logic.
  6. Configure STOMP receipts and suspension

    main

    STOMP receipts allow a client to confirm that a server has received a specific frame. Krossbow supports this via two mechanisms:

    1. Auto-receipts: If auto-receipt is enabled in your StompConfig, a receipt header is automatically added to all client frames that support it. When a receipt is present, the method used to send the frame will suspend (wait) until the corresponding RECEIPT frame is received from the server.
    2. Manual receipts: If auto-receipt is disabled, you can manually provide a receipt header in the parameters of certain method overloads.

    Error Handling:

    • If a receipt header is present but no RECEIPT frame is received within the configured receipt-timeout, a LostReceiptException is thrown.
    • If no receipt is provided (and auto-receipt is disabled), the send method returns immediately after the underlying web socket sends the frame and will never throw LostReceiptException.
  7. Configure heart beats for connection keep-alive

    main

    Heart beats act as a keep-alive mechanism to detect if a connection has been lost. You can configure this using the heartBeat property in your StompClient configuration.

    Key behaviors:

    • Negotiation: Heart beat intervals are negotiated with the server during the connection phase. The actual intervals used are defined by the CONNECTED frame received from the server and may differ from your local configuration.
    • Automation: StompSession implementations automatically handle sending and checking heart beats based on the negotiated values.
    • Error Handling: If expected heart beats are not received within the required timeframe, a MissingHeartBeatException is thrown, which results in the failure of active subscriptions.
  8. Migrate from Krossbow 3.x to 4.x: Module changes

    main

    JSON Conversions

    The withJsonConversions helper has moved to the krossbow-stomp-kxserialization-json module. This module transitively includes kotlinx-serialization-json.

    Built-in WebSocket Clients

    Built-in websocket implementations were moved to krossbow-websocket-builtin to support pure Kotlin modules.

    • If you used WebSocketClient.default(), change your dependency to krossbow-websocket-builtin.
    • If you used the StompClient() constructor without a client argument, add a dependency on krossbow-websocket-builtin and pass the client explicitly: StompClient(WebSocketClient.builtIn()). (Note: default() was renamed to builtIn() in newer versions).