Skip to content

advanced-chat/stomp-x-spec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STOMP-X Reference Implementation

Reference server and browser client for the STOMP-X protocol defined in stomp-x-spec.md.

This repository is intentionally small and explicit: it is meant to be easy to inspect while still demonstrating required STOMP-X behavior.

Specification Site

GitHub Pages hosts the spec at:

  • https://advanced-chat.github.io/stomp-x-spec/

Deployment is automated via .github/workflows/pages.yml on pushes to main.

Repository Layout

  • stomp-x-spec.md: STOMP-X protocol specification used by this project
  • server/main.go: Go WebSocket STOMP/STOMP-X reference server
  • server/main_test.go: unit tests for core protocol behavior
  • client/src/app.ts: browser TypeScript STOMP-X client
  • client/index.html: test UI served by the Go process

Requirements

  • Go 1.22+
  • Node.js 20+ and npm

Quick Start

  1. Build the browser client:
npm --prefix client install
npm --prefix client run build
  1. Start the server:
go run ./server
  1. Open the UI:
  • http://localhost:8080/index.html

Endpoints

  • Native STOMP WebSocket endpoint: ws://localhost:8080/stomp-x/websocket
  • SockJS base path (exposed): http://localhost:8080/stomp-x
  • SockJS nested path (exposed): http://localhost:8080/stomp-x/*

Notes:

  • /stomp-x/websocket is fully implemented.
  • /stomp-x and /stomp-x/* are currently placeholders that return 501 Not Implemented (path exposure only).

Protocol Behavior Implemented

Session Establishment

  • Accepts CONNECT or STOMP.
  • Requires accept-version containing 1.2.
  • Requires StompX-User and StompX-User-Agent.
  • Returns CONNECTED with:
    • version: 1.2
    • session: <generated session id>
    • heart-beat (echoed from request when provided; otherwise 0,0)

Supported Commands

  • CONNECT / STOMP
  • SUBSCRIBE
  • UNSUBSCRIBE
  • SEND
  • ACK
  • NACK
  • DISCONNECT

Destination Rules

  • SEND is restricted to /application/....
  • SUBSCRIBE is allowed for:
    • /topic/...
    • /user/queue/...
    • /application/... (for relays)

Event Envelope

Domain MESSAGE payloads use the STOMP-X envelope:

{
  "type": "event.type",
  "resource": {}
}

Action + Receipt Correlation

  • If a client supplies receipt on SEND, server emits RECEIPT.
  • Action-result MESSAGE frames include receipt-id matching the request.

Relay Behavior

  • Relay destinations are treated as one-shot interactions:
    • exact .relay forms
    • common .relay.* forms (page/cursor variants)
  • After a relay response is sent, the server removes the subscription.
  • Header override precedence is implemented for page/cursor parameters:
    • SUBSCRIBE headers override destination-encoded parameters for shared keys.

ACK Modes

Server supports:

  • ack:auto (default on missing/invalid mode)
  • ack:client
  • ack:client-individual

For non-auto subscriptions, each MESSAGE includes both:

  • message-id
  • ack

ACK/NACK handling:

  • Client must ACK/NACK with id matching MESSAGE ack header.
  • client-individual: only referenced message is acknowledged.
  • client: cumulative ack for referenced + prior unacked messages on same subscription.

Structured Error Delivery

Application errors are delivered to /user/queue/errors with JSON payload:

{
  "error": "ErrorCode",
  "message": "Human readable message",
  "timestamp": "2026-02-10T00:00:00.000000000Z",
  "coolOffDuration": "PT5S"
}

Additional error headers when available:

  • subscription-id for SUBSCRIBE/relay-related failures
  • receipt-id when request included a receipt

If no authenticated user context exists yet, server emits STOMP ERROR.

Implemented Demo API Surface

Actions (SEND to /application/...)

  • /application/echo.action
  • /application/channels.create
  • /application/channels/{channel_id}.messages.create

Topic/Queue Subscriptions

  • /topic/echo
  • /topic/channels
  • /topic/channels/{channel_id}.messages
  • /user/queue/errors

Relay Subscriptions

  • /application/user.relay
  • /application/user.read_file_access_grant.relay
  • /application/user.write_file_access_grant.relay
  • /application/channels.count.relay
  • /application/channels/{channel_id}.relay
  • /application/channels.relay.page.{page}.size.{size}.sort.{sort}
  • /application/channels/{channel_id}.messages.count.relay
  • /application/channels/{channel_id}.messages.relay.page.{page}.size.{size}.sort.{sort}
  • /application/channels/{channel_id}.messages.relay.start.{start}.next.{next}.size.{size}.relation.{relation}

Client Notes

The browser client (client/src/app.ts):

  • Sends STOMP 1.2 CONNECT headers including required STOMP-X user headers.
  • Subscribes with client-individual by default.
  • Sends receipt on SEND, SUBSCRIBE, UNSUBSCRIBE, and DISCONNECT.
  • Automatically ACKs MESSAGE frames for non-auto subscriptions.
  • Validates/logs event envelopes and structured error payloads.

Testing

Run server tests:

go test ./...

Build/check client TypeScript:

npm --prefix client run build

Conformance Matrix

Status labels:

  • Implemented: behavior is present in this reference implementation.
  • Partial: requirement is partially covered, intentionally limited, or only exposed as a placeholder.
  • Not Implemented: out of scope for this sample.
Requirement Spec Section Status Notes
STOMP 1.2 negotiation (accept-version:1.2) 4.1 Implemented CONNECT/STOMP rejected unless 1.2 is advertised.
Required CONNECT headers (StompX-User, StompX-User-Agent) 5.1 Implemented Missing values return STOMP ERROR and close the connection.
CONNECTED includes version and session 5.4 Implemented CONNECTED includes version:1.2 and generated session id.
/stomp-x/websocket endpoint exposed 3.2 Implemented Native WebSocket endpoint is fully implemented.
/stomp-x SockJS base exposed 3.2 Partial Path is exposed, but SockJS transport semantics are not implemented (501 placeholder).
Absolute destination namespaces (/application, /topic, /user/queue) 6.1 Implemented Server enforces send/subscribe namespace usage.
Error queue at /user/queue/errors 6.2 / 11.1 Implemented Structured application errors are delivered as MESSAGE frames.
Event envelope shape (type, resource) 7.1 Implemented Domain MESSAGE payloads follow STOMP-X envelope.
Unknown envelope fields ignored by client 7.2 Implemented Client parser accepts additional fields.
Action receipt behavior (RECEIPT + receipt-id on outcomes) 8.2 Implemented SEND with receipt gets RECEIPT and correlated outcome MESSAGE.
Relay lifecycle one-shot behavior 9.2 Implemented Relay subscriptions are removed after response delivery.
Relay parameter precedence (headers override path) 9.3 Implemented Page/cursor relay handlers prefer SUBSCRIBE header values.
Common relay path forms (page/cursor) 9.4 Implemented Both page and cursor relay patterns are supported.
ACK modes: auto, client, client-individual 10.2 Implemented All required modes supported, invalid values default to auto.
message-id and ack headers on manual-ack MESSAGE frames 10.3 Implemented Applied to domain and error MESSAGE delivery paths.
Error correlation headers (subscription-id, receipt-id) 11.2 Implemented Added when source context is available.
STOMP ERROR fallback before user context exists 11.3 Implemented Used for pre-auth/sessionless error conditions.
API key carriage acceptance (api-key, Api-Key) 3.3 Partial Endpoint accepts query/header pass-through, but no validation is enforced.
Auth params Base64 JSON (StompX-Auth-Params) 5.3 Not Implemented Optional auth extension is not interpreted in this sample.
Streams/binary upload endpoints 12 Not Implemented HTTP stream upload profile is out of scope for this server.
TLS requirement in deployment 13 Not Implemented Demo server runs plain HTTP/WS; TLS expected at deployment edge.

Current Gaps / Non-Goals

  • Full SockJS transport is not implemented; only required path exposure exists.
  • No authentication backend or API-key validation is enforced in this sample.
  • In-memory store only; no persistence.
  • No TLS termination in this demo process.

About

STOMP-X is a convention-based extension to STOMP 1.2 for building structured, asynchronous APIs over message-oriented transports such as WebSocket and SockJS.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors