Documentation Index
Fetch the complete documentation index at: https://api-docs.rhombus.community/llms.txt
Use this file to discover all available pages before exploring further.
Esta página fue traducida automáticamente. Si encuentra errores o tiene sugerencias, contáctenos.
Rhombus utiliza STOMP 1.2 (Streaming Text Oriented Messaging Protocol) sobre WebSocket para la entrega de eventos en tiempo real. Esta página es una referencia del protocolo para desarrolladores que necesitan entender o implementar el framing de STOMP a bajo nivel.
¿Qué es STOMP?
STOMP es un protocolo de mensajería simple y basado en texto que proporciona un formato de cable interoperable para los brokers de mensajes. Define un pequeño conjunto de comandos (frames) para conectar, suscribirse, enviar y desconectar. Rhombus usa STOMP porque proporciona mensajería pub/sub estructurada sobre un transporte WebSocket estándar.
Cada frame STOMP sigue esta estructura:
COMMAND\n
header-key:header-value\n
header-key:header-value\n
\n
body (optional)
\x00
- COMMAND: Una sola palabra que identifica el tipo de frame (por ejemplo,
CONNECT, MESSAGE)
- Headers: Cero o más pares
key:value, uno por línea
- Línea vacía: Separa los headers del cuerpo
- Cuerpo: Carga útil opcional (típicamente JSON para frames MESSAGE)
- Byte nulo (
\x00): Termina cada frame
Ejemplo: frame CONNECT sin procesar
CONNECT\n
accept-version:1.2\n
heart-beat:10000,10000\n
\n
\x00
Frames del cliente al servidor
CONNECT
Inicia la sesión STOMP después de que la conexión WebSocket esté abierta.
| Header | Requerido | Valor | Descripción |
|---|
accept-version | Sí | 1.2 | Versión del protocolo STOMP |
heart-beat | Sí | 10000,10000 | Intervalo de envío del cliente y el intervalo deseado de recepción (ms) |
CONNECT
accept-version:1.2
heart-beat:10000,10000
\x00
SUBSCRIBE
Se suscribe a un tópico de destino para recibir mensajes.
| Header | Requerido | Valor | Descripción |
|---|
id | Sí | sub-0 | Identificador de suscripción definido por el cliente |
destination | Sí | /topic/change/{orgUuid} | Ruta del tópico al cual suscribirse |
SUBSCRIBE
id:sub-0
destination:/topic/change/a1b2c3d4-e5f6-7890-abcd-ef1234567890
\x00
El id de la suscripción es definido por el cliente. Usa cualquier cadena única. Si creas múltiples suscripciones, cada una debe tener un id distinto.
DISCONNECT
Indica una desconexión limpia e intencional.
No se requieren headers ni cuerpo. Después de enviar DISCONNECT, cierra la conexión WebSocket subyacente.
Frames del servidor al cliente
CONNECTED
Enviado por el servidor en respuesta a un CONNECT exitoso.
| Header | Valor | Descripción |
|---|
version | 1.2 | Versión STOMP negociada |
heart-beat | 10000,10000 | Intervalos de heartbeat de envío/recepción del servidor |
CONNECTED
version:1.2
heart-beat:10000,10000
\x00
MESSAGE
Entrega un evento desde un tópico suscrito.
| Header | Valor | Descripción |
|---|
destination | /topic/change/{orgUuid} | El tópico al que pertenece este mensaje |
message-id | Generado por el servidor | Identificador único del mensaje |
subscription | sub-0 | Coincide con el id de la suscripción |
MESSAGE
destination:/topic/change/a1b2c3d4-e5f6-7890-abcd-ef1234567890
message-id:msg-001
subscription:sub-0
{"entity":"POLICY_ALERT","entityUuid":"x1y2z3","type":"CREATE","timestampMs":1711843200000}
\x00
El cuerpo siempre es un objeto JSON que contiene la carga útil del evento.
Heartbeats
Los heartbeats mantienen viva la conexión y detectan fallos. Se negocian durante el intercambio CONNECT/CONNECTED.
Un heartbeat es un único carácter de salto de línea:
Sin comando, sin headers, sin terminador nulo. Solo \n.
Negociación
El header heart-beat usa el formato cx,cy donde:
cx = intervalo mínimo (ms) al que el cliente puede enviar heartbeats
cy = intervalo deseado (ms) al que el cliente quiere recibir heartbeats
El servidor de Rhombus usa 10000,10000 (10 segundos en ambas direcciones).
Comportamiento
| Dirección | Intervalo | Qué ocurre en caso de falla |
|---|
| Cliente al servidor | 10 segundos | El servidor puede cerrar la conexión |
| Servidor al cliente | 10 segundos | El cliente debe asumir que la conexión está muerta y reconectar |
Implementación
# Sending heartbeats
import threading
def send_heartbeats(ws, stop_event, interval=10):
while not stop_event.is_set():
ws.send("\n")
stop_event.wait(interval)
# Receiving heartbeats
def parse_frame(raw):
raw = raw.strip("\n\r")
if not raw or raw == "\x00":
return None # This is a heartbeat, safe to ignore
# ... parse as normal STOMP frame
Guía de análisis de frames
Algoritmo de análisis paso a paso
1. Read WebSocket text message
2. Strip leading newlines/carriage returns
3. If empty or just \x00 → heartbeat, return null
4. Strip trailing \x00
5. Split on "\n\n" (first occurrence) → [header_block, body]
6. Split header_block on "\n" → [command, header1, header2, ...]
7. For each header line, split on first ":" → key, value
8. Return {command, headers, body}
Casos especiales
| Entrada | Resultado |
|---|
\n | Heartbeat (nulo) |
\n\n\n | Heartbeat (nulo) |
\x00 | Heartbeat (nulo) |
| Frame sin cuerpo | El cuerpo es una cadena vacía |
Valor de header que contiene : | Dividir solo en los primeros dos puntos |
Intercambio completo de frames
Aquí está la secuencia completa de frames para una sesión típica:
Client Server
│ │
│ CONNECT │
│ accept-version:1.2 │
│ heart-beat:10000,10000 │
│ \x00 │
├─────────────────────────────────────►│
│ │
│ CONNECTED │
│ version:1.2 │
│ heart-beat:10000,10000 │
│ \x00 │
│◄─────────────────────────────────────┤
│ │
│ SUBSCRIBE │
│ id:sub-0 │
│ destination:/topic/change/{org} │
│ \x00 │
├─────────────────────────────────────►│
│ │
│ \n (heartbeat) │
├─────────────────────────────────────►│
│ │
│ \n (heartbeat) │
│◄─────────────────────────────────────┤
│ │
│ MESSAGE │
│ destination:/topic/... │
│ │
│ {"entity":"..."} │
│ \x00 │
│◄─────────────────────────────────────┤
│ │
│ \n (heartbeat) │
├─────────────────────────────────────►│
│ │
│ DISCONNECT │
│ \x00 │
├─────────────────────────────────────►│
│ │
│ [WebSocket close] │
│◄─────────────────────────────────────┤
Diferencias respecto al STOMP 1.2 completo
La implementación de Rhombus utiliza un subconjunto de STOMP 1.2. Diferencias notables:
| Característica | Spec STOMP 1.2 | Implementación de Rhombus |
|---|
Comando SEND | Soportado | No se usa (solo push del servidor) |
UNSUBSCRIBE | Soportado | No es necesario (un solo tópico) |
ACK/NACK | Soportado | No se usa (auto-acknowledge) |
RECEIPT | Soportado | No se usa |
Frame ERROR | Soportado | Puede enviarse en errores del servidor |
Header content-length | Opcional | No requerido |
| Soporte de transacciones | Soportado | No se usa |
Esto significa que no necesitas una librería completa de cliente STOMP. El subconjunto del protocolo es lo suficientemente simple como para implementarlo manualmente, como se muestra en los Ejemplos de código.