Elixir STOMP Client
A custom STOMP protocol client implementation for Elixir that provides precise control over message formatting, especially content-length headers. Features automatic reconnection, heartbeat support, and callback-based message handling.
Features
- Custom Message Formatting: Control over content-length headers (can omit content-length like Go's NoContentLength)
- Automatic Reconnection: Automatic reconnection with configurable retry intervals
- Heartbeat Support: Built-in heartbeat mechanism to keep connections alive
- Callback-based Handling: Process-based callback system for handling connection events and messages
- STOMP 1.2 Compatible: Full support for STOMP 1.2 protocol
- Subscription Management: Easy subscription and unsubscription management
Installation
Add elixir_stomp_client to your list of dependencies in mix.exs:
def deps do
[
{:elixir_stomp_client, "~> 0.1.0"}
]
endUsage
Basic Connection
# Define a callback handler process
defmodule MyStompHandler do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_) do
{:ok, %{}}
end
def handle_info({:stomp_client, :on_connect, frame}, state) do
IO.puts("Connected to STOMP server!")
{:noreply, state}
end
def handle_info({:stomp_client, :on_message, message}, state) do
IO.puts("Received message: #{inspect(message)}")
{:noreply, state}
end
def handle_info({:stomp_client, :on_disconnect, _}, state) do
IO.puts("Disconnected from STOMP server")
{:noreply, state}
end
def handle_info({:stomp_client, :on_connect_error, error}, state) do
IO.puts("Connection error: #{inspect(error)}")
{:noreply, state}
end
end
# Start the handler
{:ok, _} = MyStompHandler.start_link(nil)
# Connect to STOMP server
{:ok, client} = StompClient.connect([
host: "localhost",
port: 61613,
username: "guest",
password: "guest"
], callback_handler: MyStompHandler)Sending Messages
# Send a simple message
StompClient.send(client, "/queue/test", "Hello World!")
# Send a message with custom headers
StompClient.send(client, "/queue/test", "Hello World!", [
{"custom-header", "custom-value"}
])Subscribing to Destinations
# Subscribe to a queue
StompClient.subscribe(client, "/queue/test")
# Subscribe with a selector
StompClient.subscribe(client, "/queue/test", selector: "priority > 5")
# Subscribe with custom ID
StompClient.subscribe(client, "/queue/test", id: "my-subscription")Unsubscribing
StompClient.unsubscribe(client, "/queue/test")Disconnecting
StompClient.disconnect(client)Configuration Options
When connecting, you can provide the following options:
host- STOMP server hostname (required)port- STOMP server port (default: 61613)usernameorlogin- Authentication usernamepasswordorpasscode- Authentication passwordcallback_handler- Process to receive callback messages (required)
Callback Messages
Your callback handler will receive the following messages:
{:stomp_client, :on_connect, frame}- When successfully connected{:stomp_client, :on_message, message}- When a message is received{:stomp_client, :on_disconnect, nil}- When disconnected{:stomp_client, :on_connect_error, error}- When connection fails{:stomp_client, :on_send, frame}- When a frame is sent (optional)
Message Structure
Received messages have the following structure:
%{
"destination" => "/queue/test",
"body" => "message content",
# ... other STOMP headers
}Advanced Usage
Custom Frame Building
The client provides two frame building methods:
- Standard frames (with content-length): Used for CONNECT, SUBSCRIBE, etc.
- Frames without content-length: Used for SEND messages (configurable)
This allows compatibility with different STOMP server implementations that may have different content-length requirements.
Heartbeat Configuration
The client automatically sends heartbeats every 25 seconds when connected. The server heartbeat timeout is set to 30 seconds.
Error Handling
The client includes robust error handling with automatic reconnection. Connection failures trigger reconnection attempts every 5 seconds.
License
MIT License. See LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request