# TR-369 WebSocket vs MQTT vs STOMP: ¿cómo se comparan los transportes de USP?

Equipo de ingeniería de Dodderware · Publicado 2026-10-28 · https://blog.dodderware.com/es/mtp-usp-websocket-mqtt-stomp/

[Read in English](https://blog.dodderware.com/usp-mtp-websocket-mqtt-stomp/)

> **Respuesta corta:** TR-369 define cuatro Message Transfer Protocols (MTP) para transportar los USP Records. WebSocket une directamente un Agente y un Controlador con una sola sesión de larga duración. STOMP y MQTT enrutan los Records a través de un broker, por destino o por Topic. El MTP UNIX Domain Socket conecta un Agente y un Controlador en procesos separados del mismo dispositivo. CoAP quedó obsoleto en USP 1.3.

Antes de que un Agente y un Controlador intercambien un solo mensaje USP, tienen que ponerse de acuerdo en cómo viaja.
TR-369 llama a esa capa **Message Transfer Protocol (MTP)** y define cuatro. El que elijas decide si tus equipos
necesitan un broker, cómo se identifican y cómo se comportan después de una caída. Esta guía compara WebSocket, STOMP,
MQTT y UNIX Domain Socket usando solo lo que dice la especificación.

## ¿Qué es un Message Transfer Protocol?

Un MTP es el protocolo de la capa inferior a USP que transporta un Message, por ejemplo WebSocket (§1.4). El USP
Record es la carga útil del MTP (§4.1.3), así que cada binding responde las mismas preguntas: cómo conectarse, cómo
llevar un Record y cómo avisar de un fallo. En nuestra [guía de TR-369](https://blog.dodderware.com/es/que-es-tr-369/) verás cómo se anidan
Records y Messages.

Algunas reglas valen para todos los MTP (§4.1). Agentes y Controladores pueden soportar más de uno, y los Endpoints
siempre responden por el MTP en el que recibieron el mensaje (§4.1.1). Una vez establecido el canal, el Agente que
puede hacerlo envía el Connect Record del MTP en uso, como `WebSocketConnectRecord` o `MQTTConnectRecord` (R-MTP.6), y
debería enviar un `DisconnectRecord` antes de irse (R-MTP.7). Desde USP 1.2, los problemas con un Record se informan
con USP Records en lugar de mensajes propios de cada MTP, con códigos de error del 7100 al 7199 (§4.1.4, Issue
History).

## ¿Cómo se comparan los cuatro MTP?

| MTP                       | Camino entre Endpoints               | El emisor se identifica con           | La carga se marca con                       | Seguridad de transporte         |
| ------------------------- | ------------------------------------ | ------------------------------------- | ------------------------------------------- | ------------------------------- |
| WebSocket (§4.3)          | Una sesión directa por par           | `eid` en la URI del handshake         | El subprotocolo `v1.usp`, tramas binarias   | TLS (R-WS.22)                   |
| STOMP (§4.4)              | Por un servidor STOMP, según destino | Encabezado `endpoint-id`              | `content-type: application/vnd.bbf.usp.msg` | TLS 1.2 o superior (R-STOMP.36) |
| MQTT (§4.5)               | Por un servidor MQTT, según Topic    | User Property `usp-endpoint-id` (5.0) | Content Type `usp.msg` (5.0)                | TLS 1.2 o superior (R-MQTT.48)  |
| UNIX Domain Socket (§4.6) | Entre procesos del mismo dispositivo | TLV de Handshake (tipo 1)             | TLV de USP Record (tipo 3)                  | TLS opcional (§4.6.4)           |

La diferencia que más pesa es conexión directa frente a conexión con broker. Con WebSocket, los dos Endpoints sostienen
la sesión. Con STOMP y MQTT, cada Endpoint mantiene una sesión con un servidor que enruta los Records por él.

## ¿Cómo funciona el MTP WebSocket?

El binding WebSocket usa RFC 6455, con sesiones de larga duración que se reutilizan para los Records siguientes (§4.3,
§4.3.2). El Agente debe poder abrir una sesión y también aceptar la que abra un Controlador (R-WS.5, R-WS.6). En
general la abre el Agente, por seguridad, para no exponer un puerto abierto hacia Internet, y entre dos Endpoints se
usa como máximo una sesión abierta (§4.3.2, R-WS.4).

El handshake lleva dos datos propios de USP (§4.3.2.1):

- **El subprotocolo.** El cliente envía `v1.usp` en el encabezado `Sec-WebSocket-Protocol` y el servidor lo devuelve
  (R-WS.9 a R-WS.11). Si no vuelve, el cliente no establece la sesión (R-WS.12).
- **El Endpoint ID del cliente.** Con TLS, el servidor no sabe quién se conecta sin mirar dentro del certificado, así
  que el cliente agrega `eid=` y su Endpoint ID a la query de la URI (R-WS.10b). El requisito anterior, usar una
  WebSocket Extension, se eliminó en USP 1.3 (R-WS.10a).

Los Records viajan en tramas de datos binarias (R-WS.14). Quien envía no debería fragmentarlos, pero quien recibe debe
aceptar fragmentos (R-WS.14a, R-WS.14b). Si un Record no se puede extraer, por ejemplo porque llegó en una trama de
texto, el receptor cierra la conexión con el código de estado 1003 (R-WS.16). Los Agentes mantienen viva la sesión con
tramas Ping y Pong, a un intervalo configurable (R-WS.17, R-WS.18).

> **¿Sabías que…?**
>
> Después de una caída, el Agente no reconecta con un temporizador fijo. Con los valores de fábrica, una espera mínima de
> 5 segundos y un multiplicador de 2000, el primer reintento espera entre 5 y 10 segundos y la ventana se duplica cada
> vez. Desde el décimo reintento, el Agente espera entre 2560 y 5120 segundos, unos 43 a 85 minutos. Un Controlador
> puede ajustar ambos valores si el Agente implementa `SessionRetryMinimumWaitInterval` y
> `SessionRetryIntervalMultiplier` (R-WS.19).

> **Dónde encaja DWS Support**
>
> WebSocket es el MTP que DWS Support usa hoy. Su controlador USP nativo se conecta a los Agentes por WebSocket, ws o
> wss, e intercambia USP Records con ellos. Se desarrolló y probó contra obuspa, el Agente USP de código abierto del
> Broadband Forum, y la misma consola gestiona cada dispositivo por TR-069 o TR-369, con el protocolo elegido para cada
> uno.
>
> [Conoce DWS Support](https://dodderware.com/es/productos/dws-support/)

## ¿Cómo usan STOMP y MQTT un broker?

Los dos bindings con broker siguen los mismos pasos básicos: negociar TLS si está configurado, conectarse al
servidor, suscribirse y enviar USP Records (§4.4, §4.5).

1. **Cliente STOMP o MQTT** (Agente): Se suscribe a su propio destino o Topic y agrega una dirección de respuesta a todo lo que envía.
2. **Servidor STOMP o MQTT** (Broker): Autentica a cada cliente y limita a qué puede suscribirse.
   - STOMP: destino
   - MQTT: Topic
3. **Cliente STOMP o MQTT** (Controlador): Envía al destino o Topic del Agente y responde en la dirección de respuesta.

*MTP con broker. El Agente y el Controlador mantienen cada uno su propia sesión con el servidor STOMP o MQTT, que enruta cada USP Record por destino o por Topic. Diagrama de Dodderware, basado en TR-369 §4.4 y §4.5.*

Como no hay sesión directa, todo lo que pasa por el broker indica dónde responder. STOMP usa el encabezado
`reply-to-dest` (R-STOMP.21). MQTT exige un Topic de respuesta (“reply to”) en cada paquete PUBLISH: en la propiedad
Response Topic con MQTT 5.0, o después de `/reply-to=` al final del Topic Name con MQTT 3.1.1 (R-MQTT.22 a R-MQTT.24).
El broker también puede indicarle al Agente dónde escuchar: `subscribe-dest` en STOMP, la User Property
`subscribe-topic` en MQTT 5.0 (R-STOMP.6, §4.5.2).

El broker tiene obligaciones concretas. Un servidor STOMP debe autenticar a los clientes y dejar que cada uno se
suscriba solo a su propio destino (R-STOMP.34). Un servidor MQTT debe autenticar a los clientes y soportar una Access
Control List que limite los Topics que cada uno puede usar (R-MQTT.42).

- **STOMP**, Simple Text Oriented Message Protocol, se usa en su versión 1.2 (§4.4). Los Endpoints USP envían su
  Endpoint ID en el encabezado `endpoint-id` (R-STOMP.4), se suscriben con `ack` en “auto” y nunca envían tramas de
  transacción ni de acuse de recibo (R-STOMP.17, R-STOMP.26, R-STOMP.27).
- **MQTT**, Message Queuing Telemetry Transport, se sumó a USP en la versión 1.1 (Issue History). Los clientes deben
  implementar MQTT 5.0 y pueden sumar 3.1.1 (R-MQTT.1, R-MQTT.2). La versión 5.0 importa porque en 3.1.1 el cliente no
  tiene una forma sencilla de pasarle su Endpoint ID al servidor, y el servidor no tiene cómo indicarle al cliente su
  Topic de respuesta (§4.5.1.1). Los Agentes deben soportar MQTT sobre TCP, y MQTT sobre WebSockets está permitido
  (R-MQTT.3). Los Endpoints deben soportar QoS 0 y 1 (R-MQTT.20), y desde USP 1.5 deberían soportar ALPN en el
  handshake TLS (R-MQTT.48a).

En los registros DNS-SD, un Endpoint detrás de un broker anuncia la dirección del broker, no la suya (R-STOMP.32,
R-MQTT.38). Lo explicamos en [cómo encuentra un Agente USP a su Controlador](https://blog.dodderware.com/es/descubrimiento-usp-dhcp-mdns/).

## ¿Cuándo tiene sentido el MTP UNIX Domain Socket?

Cuando el Agente y el Controlador viven en el mismo equipo. Este MTP interno, agregado en USP 1.3, comunica procesos
separados dentro de un mismo dispositivo (§4.6). El socket se asocia a una ruta de archivo local en lugar de un host y
un puerto, cada Endpoint actúa como servidor o como cliente pero no ambos, y no hace falta anunciar nada por mDNS
(§4.6.1).

- **Frame**: Un Header y luego uno o más campos TLV. (Sincronización: 0x5f 0x55 0x53 0x50 (“_USP”), Longitud del resto: 4 bytes)
  - **Campo TLV**: Tipo 1 Handshake, 2 Error, 3 USP Record, 4 Password. (Type: 1 byte, Length: 4 bytes, Value)
    - **USP Record**: La codificación binaria en Protocol Buffers del Record, como valor de un TLV de tipo 3.

*Por dentro de una trama (Frame) del MTP UNIX Domain Socket. Diagrama de Dodderware, basado en TR-369 §4.6.1.3.*

Los dos lados intercambian TLV de Handshake con sus Endpoint IDs antes de cualquier Record, y el cliente que no recibe
respuesta en 30 segundos cierra la conexión (R-UDS.16 a R-UDS.18). Si la conexión se cae, el cliente reintenta dentro
de un lapso aleatorio de 1 a 5 segundos (R-UDS.5). El cifrado no es obligatorio, aunque TLS es una opción desde USP
1.4, y USP 1.5 agregó el TLV de Password para autenticar con un secreto compartido (§4.6.4, Issue History).

## ¿Qué MTP necesitan TLS?

La base es R-MTP.0: un MTP debe usar transporte seguro cuando los mensajes USP cruzan fronteras entre redes
(§4.1.2). Dentro de la LAN del usuario final, la seguridad del MTP puede no ser necesaria. Se espera que los MTP
sobre TCP implementen al menos TLS 1.2, y cuando se usa TLS, el Agente debe exigirle a su par un certificado X.509
(§4.1.2, R-MTP.1).

Los bindings de MTP dan seguridad punto a punto, así que en un MTP con broker ese TLS protege cada tramo hasta el
broker, no todo el camino entre Agente y Controlador (§6.4). Para eso, USP tiene los Trusted Brokers y el Secure
Message Exchange de extremo a extremo, que explicamos en [seguridad en TR-369](https://blog.dodderware.com/es/seguridad-tr-369/).

## ¿Sabías que…?

- Una sesión WebSocket de USP solo se abre si el servidor devuelve el subprotocolo v1.usp en su encabezado Sec-WebSocket-Protocol. (TR-369 §4.3.2.1, R-WS.12)
- Los Endpoints USP que usan clientes MQTT deben implementar MQTT 5.0. El soporte de MQTT 3.1.1 es opcional. (TR-369 R-MQTT.1, R-MQTT.2)
- Si una trama WebSocket trae un USP Record que no se puede extraer, el receptor cierra la conexión con el código de estado 1003. (TR-369 R-WS.16)
- Toda trama del MTP UNIX Domain Socket empieza con los cuatro bytes 0x5f 0x55 0x53 0x50, que forman “_USP”. (TR-369 R-UDS.8)
- El MTP UNIX Domain Socket llegó en USP 1.3, y MQTT en USP 1.1. (TR-369 Issue History)

## Preguntas frecuentes

### ¿Qué transportes soporta USP?

TR-369 define cuatro Message Transfer Protocols, WebSocket, STOMP, MQTT y UNIX Domain Socket. Un quinto, CoAP, se declaró en desuso (deprecated) en USP 1.2 y quedó obsoleto en USP 1.3 (§4.2).

### ¿Cuál es el subprotocolo WebSocket de USP?

Es v1.usp. El cliente WebSocket lo envía en el encabezado Sec-WebSocket-Protocol, el servidor lo devuelve, y si el cliente no lo recibe de vuelta no establece la sesión (§4.3.2.1, R-WS.9, R-WS.12).

### ¿USP sobre MQTT exige MQTT 5.0?

Sí. Los Endpoints USP que usan clientes MQTT deben implementar MQTT 5.0 y pueden implementar además MQTT 3.1.1. Los servidores MQTT deben implementar 5.0 y deberían implementar 3.1.1 (R-MQTT.1, R-MQTT.2, R-MQTT.39, R-MQTT.40).

### ¿Quién abre la conexión WebSocket, el Agente o el Controlador?

Cualquiera de los dos. El Agente debe poder iniciar una sesión WebSocket y también aceptar la que abra un Controlador, y entre dos Endpoints se usa como máximo una sesión abierta. En general la abre el Agente, para no exponer un puerto abierto hacia Internet (§4.3.2, R-WS.4 a R-WS.6).

### ¿TLS es obligatorio en los transportes de USP?

Un MTP debe usar transporte seguro cuando los mensajes USP cruzan fronteras entre redes, y se espera que los MTP que corren sobre TCP implementen al menos TLS 1.2 (§4.1.2, R-MTP.0). El MTP UNIX Domain Socket no sale del dispositivo, así que ahí TLS es opcional (§4.6.4).

### ¿Un Agente puede usar más de un MTP?

Sí. Agentes y Controladores pueden soportar varios MTP, un Agente puede configurarse para llegar a un mismo Controlador por más de uno, y las respuestas siempre vuelven por el MTP en el que llegó el mensaje (§4.1.1).

## Fuentes

- Broadband Forum, TR-369 – The User Services Platform, Issue 1 Amendment 5 (USP 1.5), enero de 2026.
- Dodderware, documentación de producto e ingeniería de DWS Support.
- §1.4, §4, §4.1.1: Definición de MTP, Message Transfer Protocols, soporte de varios MTP
- §4.1.2: Protección de los MTP (R-MTP.0, R-MTP.1)
- §4.1.3, §4.1.4, §4.1.5: Encapsulamiento del USP Record, errores de Record, Connect y Disconnect Records
- §4.2: El binding CoAP, obsoleto
- §4.3: Binding WebSocket (R-WS.4 a R-WS.22)
- §4.4: Binding STOMP (R-STOMP.2 a R-STOMP.36)
- §4.5: Binding MQTT (R-MQTT.1 a R-MQTT.48a)
- §4.6: Binding UNIX Domain Socket (R-UDS.1 a R-UDS.25)
- Issue History: MQTT llega en USP 1.1, UNIX Domain Socket en USP 1.3, ALPN para MQTT en USP 1.5

[Leer la especificación TR-369](https://usp.technology/specification/index.htm)

TR-369 © The Broadband Forum. Todos los derechos reservados. Citado brevemente y parafraseado con fines explicativos; los diagramas son de Dodderware.

---

**Gestiona equipos TR-069 y TR-369 desde una sola consola.** DWS Support reúne cada ONT y router del hogar en una consola web, hable el protocolo que hable: TR-069 por GenieACS o un ACS integrado, TR-369 por un controlador USP nativo. Se instala en tu propia infraestructura. [Solicita una demo](https://dodderware.com/es/productos/dws-support/#get-started)
