2012-06-20 14 views
9

La empresa para la que estoy trabajando ha evaluado MQTT y ha decidido utilizarla como una plataforma central de mensajería para un sistema a gran escala. La razón principal es cuán compacto es el protocolo y cuán fácil puede ser realmente implementado. Sin embargo, tengo un único problema con MQTT y estoy buscando una respuesta a la siguiente pregunta:MQTT messageId implementación práctica

Los mensajes QoS1 y QoS2 requieren confirmación del cliente. Lo único que sé sobre el mensaje (identificándolo) al recibir PUBACK, PUBREC, PUBREL y PUBCOMP es messageId y clientId. El ID del mensaje es un int16 sin firmar, por lo que el valor máximo es 65535. No parece ser lo suficientemente grande para los clientes de larga ejecución, digamos un año, enviando 15 mensajes de QoS2 por hora.

¿No estoy seguro de si hay alguna otra forma de identificar el mensaje? Me gustaría ser tan obediente con el estándar como sea posible.

Respuesta

19

Probablemente, el primer punto para dejar en claro es que los identificadores de mensajes se manejan por cliente y por dirección. Es decir, el intermediario creará un ID de mensaje para cada mensaje saliente con QoS> 0 para cada cliente que esté conectado y estos ID de mensaje serán completamente independientes de cualquier otro ID de mensaje utilizado para el mismo mensaje publicado para otros clientes. Del mismo modo, cada cliente genera sus propios ID de mensajes para los mensajes que envía.

El ID del mensaje no tiene que ser exclusivo, por lo que su cliente enviará 15 mensajes por hora con QoS nivel 2 simplemente se desbordará en algún momento. La verdadera limitación es que solo puede haber un máximo de 65535 mensajes por dirección "en vuelo" a la vez (es decir, en parte a través del protocolo de mensaje). Una vez que un mensaje con un ID dado ha sido procesado por completo, ese identificador de mensaje puede ser reutilizado.

Otra forma de verlo es considerar cómo funcionaría si su cliente solo tuviera un mensaje en vuelo a la vez, ya sea por la velocidad con la que se transmiten los mensajes o por el diseño en la forma en que maneja los mensajes . En este caso, puede mantener la Id. De mensaje establecida en 1 para cada mensaje porque nunca existe la posibilidad de que haya un duplicado.

Si desea admitir el envío simultáneo de varios mensajes, sería relativamente sencillo verificar que no haya duplicados de ID de mensaje antes de asignar uno nuevo.

Como la ID del mensaje es por cliente, si envía un solo mensaje a> 65535 clientes no habrá posibilidad de colisión de ID de mensaje. Si envía> 65535 mensajes a cada cliente a la vez y los flujos de mensajes no están completos, entonces habrá problemas.

Respondiendo al comentario "Me he dado cuenta de que cada corredor MQTT tiende a entregar sólo el último mensaje QoS1/2":

El corredor sólo enviará mensajes a los clientes que dispone de información. Si se conecta por primera vez, no hay forma de obtener mensajes del pasado, con una excepción: mensajes retenidos. Si un mensaje se establece como retenido, entonces es un valor de "último bien conocido". Cuando un nuevo cliente se suscribe, se le enviará el mensaje retenido inmediatamente, lo que lo hace útil para cosas que se actualizan con poca frecuencia. Sospecho que esto es a lo que te refieres. Si desea que un cliente tenga mensajes en cola cuando no está conectado, debe conectarse con la opción "limpiar sesión" deshabilitada para que el cliente sea persistente. También debe usar QoS> 0 suscripciones y QoS> 0 publicaciones. Cuando su cliente se vuelva a conectar (con la sesión limpia aún configurada como deshabilitada), los mensajes en cola serán entregados. Normalmente, puede configurar el número de mensajes para cola de esta manera en el intermediario, donde se descartarán los mensajes adicionales. Un punto importante es que los mensajes de cola para un cliente que no se ha conectado anteriormente no son compatibles con el diseño.

+0

Entiendo este punto, gracias por la respuesta por cierto. He notado que todos los intermediarios MQTT tienden a entregar solo el último mensaje QoS1/2. ¿Qué pasa si me gustaría entregar más? ¿Qué hay más de 65535? Entiendo que esto es muy poco probable, pero es posible. La solución que sugiere es buena para un número conocido de destinatarios. La situación con la que estoy lidiando es que no sé cuántos destinatarios puede haber y todavía están en la fábrica. Básicamente, podrían estar allí, pero nunca entrar. Y puede haber cientos de miles de ellos. – radekg

+0

Un punto que no dejé en claro es que el ID del mensaje es por cliente y por dirección. He actualizado la respuesta para incluir eso. – ralight

+0

También he respondido tu otro punto. Si eso no aclara las cosas, por favor deje otro comentario. – ralight

0

Para entregar más mensajes en QOS1 o QOS2, debe usar el concepto de memoria persistente. En este caso, cuando un suscriptor no está disponible, el mensaje se almacena en la memoria persistente y se entrega una vez que el suscriptor está conectado. Usted puede hacer esto en QOS0 también después de configurar el archivo mosquitto.conf.