Saltar al contenido principal

WebSocket API

TinyMQ incluye un servidor WebSocket nativo (RFC 6455) que permite comunicación full-duplex sobre una única conexión TCP persistente. Opera en el mismo puerto que el servidor HTTP (/ws).

Conexión

Conéctate al endpoint WebSocket:

ws://localhost:7800/ws

Si la autenticación está habilitada, se recomienda estrictamente proporcionar el token utilizando headers HTTP estándar Authorization: Bearer <your_token> durante el handshake inicial.

Aviso de obsolescencia

Pasar el token mediante un parámetro de consulta (p. ej. ?token=<your_token>) está obsoleto, ya que expone los secretos en los registros de proxies y en el historial del navegador.

Protocolo (TMP-WS)

TinyMQ utiliza un protocolo de comandos JSON ligero sobre WebSocket.

1. Suscribirse a un topic

Para recibir mensajes, envía un comando subscribe. Las suscripciones en WebSocket son no destructivas (Spy Mode). Consumir un mensaje a través de WebSocket no lo elimina de la queue del WAL.

Petición:

{
"command": "subscribe",
"topic": "sensor.data",
"filter_key": "status",
"filter_val": "alert"
}
  • topic: El topic o comodín (*) a escuchar.
  • filter_key y filter_val (Opcional): Smart Routing. Si se proporcionan, el broker decodificará de forma transparente el payload JSON de los mensajes encolados y solo enviará (push) aquellos que contengan este par clave-valor exacto.

Respuesta (cuando llega un mensaje):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"topic": "sensor.data",
"payload": "SGVsbG8gV29ybGQ=",
"payload_text": "Hello World",
"timestamp": "2023-10-01T12:00:00Z"
}

Nota: payload siempre está codificado en Base64. payload_text se rellena si el contenido es UTF-8 válido.

2. Publicar un mensaje

Petición:

{
"command": "publish",
"topic": "sensor.data",
"payload": "SGVsbG8gV29ybGQ="
}

3. Keep-Alive (Ping)

Para mantener la conexión activa detrás de proxies, envía un comando ping.

Petición:

{
"command": "ping"
}

Respuesta:

{
"status": "pong"
}

Arquitectura

Uso con el Go SDK

El Go SDK oficial incluye un cliente WebSocket robusto:

package main

import (
"fmt"
"github.com/x-name15/tinymq/client"
)

func main() {
wsClient := client.NewWSClient("ws://localhost:7800/ws")
wsClient.Connect()

wsClient.Subscribe("test_topic", func(msg client.Message) {
fmt.Printf("Received: %s\n", msg.PayloadText)
})

wsClient.Publish("test_topic", []byte("Hello via WebSocket"))

select{} // Block forever
}