2012-06-20 8 views
9

La società per cui lavoro ha valutato MQTT e ha deciso di utilizzarlo come piattaforma di messaggistica di base per un sistema su larga scala. Il motivo principale è la compattezza del protocollo e la facilità con cui può essere implementato. Ho un singolo problema con MQTT e sto cercando una risposta alla seguente domanda:Messaggio MQTTImplementazione pratica

I messaggi QoS1 e QoS2 richiedono la conferma dal client. L'unica cosa che so del messaggio (identificandolo) quando si riceve PUBACK, PUBREC, PUBREL e PUBCOMP è messageId e clientId. L'id del messaggio è un int16 non firmato, quindi il valore massimo è 65535. Non sembra essere abbastanza grande per i client di lunga durata, ad esempio un anno, che invia 15 messaggi QoS2 all'ora.

Non sono sicuro se esiste un altro modo per identificare il messaggio? Mi piacerebbe essere conforme allo standard possibile.

risposta

19

Probabilmente il primo punto da chiarire è che gli ID dei messaggi vengono gestiti su base client e per direzione. Ciò significa che il broker creerà un ID messaggio per ciascun messaggio in uscita con QoS> 0 per ciascun client connesso e questi ID messaggio saranno completamente indipendenti da qualsiasi altro ID messaggio utilizzato per lo stesso messaggio pubblicato su altri client. Allo stesso modo, ogni client genera i propri ID di messaggio per i messaggi che invia.

L'ID messaggio non deve essere univoco, quindi il client che invia 15 messaggi all'ora con QoS livello 2 semplicemente supererebbe a un certo punto. La vera limitazione è che non ci può essere un massimo di 65535 messaggi per direzione "in volo" in una sola volta (cioè in parte attraverso l'handshake del messaggio). Una volta che un messaggio con un determinato ID è stato completamente elaborato, l'ID messaggio può essere riutilizzato.

Un altro modo di guardare è considerare come funzionerebbe se il cliente avesse sempre avuto un solo messaggio in volo in una sola volta, sia a causa della velocità con cui i messaggi vengono trasmessi o di progettazione nel modo in cui gestisci i messaggi . In questo caso, puoi mantenere l'ID del messaggio impostato su 1 per ogni singolo messaggio perché non c'è mai la possibilità che ci sia un duplicato.

Se si desidera supportare più messaggi contemporaneamente in volo, sarebbe relativamente semplice verificare che non vi siano duplicati di ID messaggio prima di assegnarne uno nuovo.

Poiché l'ID messaggio è per client, se si invia un singolo messaggio a> 65535 client non ci sarà alcuna possibilità di collisione ID messaggio. Se invii> 65535 messaggi a ciascun client contemporaneamente e i flussi di messaggi non sono completi, ci saranno problemi.

Rispondere il commento "ho notato che tutti i broker MQTT tende a fornire solo l'ultimo messaggio QoS1/2":

Il broker solo inviare messaggi ai client che conosce. Se ti connetti per la prima volta non c'è modo di ottenere messaggi dal passato, con una sola eccezione: i messaggi conservati. Se un messaggio è impostato per essere conservato, si tratta di un valore "ultimo noto bene". Quando un nuovo cliente si iscrive, verrà inviato immediatamente il messaggio conservato che lo rende utile per le cose che vengono aggiornate di rado. Sospetto che questo sia ciò a cui ti riferisci. Se si desidera che un client abbia i messaggi in coda quando non è connesso, è necessario connettersi con l'opzione "clean session" disabilitata per rendere persistente il client. È inoltre necessario utilizzare QoS> 0 abbonamenti e QoS> 0 pubblicazioni. Quando il client si riconnette (con la sessione pulita è ancora disabilitata), i messaggi in coda verranno consegnati. Normalmente è possibile configurare il numero di messaggi da mettere in coda in questo modo nel broker, dove eventuali altri messaggi verranno scartati. Un punto importante è che i messaggi di accodamento per un client che non è stato collegato in precedenza non sono supportati dalla progettazione.

+0

Capisco questo punto, grazie per la risposta a proposito. Ho notato che ogni broker MQTT tende a recapitare solo l'ultimo messaggio QoS1/2. Cosa succede se mi piacerebbe consegnare di più? Cosa c'è di più di 65535? Capisco che questo sia altamente improbabile, ma è possibile. La soluzione suggerita va bene per un numero noto di destinatari. La situazione che sto affrontando è che non so quanti destinatari ci possono essere e sono ancora in fabbrica. Fondamentalmente, potrebbero essere lì ma non entrare mai. E potrebbero essercene centinaia di migliaia. – radekg

+0

Un punto che non ho chiarito è che l'ID del messaggio è per client e per direzione. Ho aggiornato la risposta per includerla. – ralight

+0

Ho anche risposto al tuo altro punto. Se ciò non risolve le cose per favore lascia un altro commento. – ralight

0

Per la consegna di più messaggi su QOS1 o QOS2, è necessario utilizzare il concetto di memoria persistente. In questo, quando un sottoscrittore non è disponibile, il messaggio viene memorizzato nella memoria persistente e viene consegnato una volta connesso l'utente. Puoi farlo a QOS0 anche dopo aver configurato il file mosquitto.conf.