passare da JSON a MsgPack in modo compatibile all'indietro con Paho MQTT (JavaScript)
picockpit.com fa un uso pesante di MQTT. Per la prossima versione 2.0 ho deciso di passare a MsgPack.
Perché MsgPack?
MsgPack (in realtà chiamato MessagePack - i pacchetti tendono ad usare MsgPack) è un formato binario, volto alla compatibilità con JSON, ma diminuendo la dimensione del file (che è buono per risparmiare banda e risorse del server).
Un altro vantaggio: MessagePack permette di incorporare dati binari (ci sono alcuni casi d'uso interessanti previsti per PiCockpit v2.1+).
Rispetto ad altri formati di serializzazione binari (ad esempio BSON) MsgPack mira a una maggiore compatibilità con JSON, è più compatto, e può essere decodificato come un flusso!
Messaggi conservati dal passato
A causa dei messaggi conservati che sono ancora in JSON (e anche i client legacy che inviano ancora messaggi JSON), tuttavia, la compatibilità all'indietro deve essere fornita, specialmente sul lato JavaScript.
Non fornire la compatibilità all'indietro porterà ai seguenti problemi con Paho:
onConnectFailure;Connessione MQTT non riuscita (5): AMQJS0005E Errore interno. Messaggio di errore: AMQJS0009E Dati UTF malformati:ad -4f ., Stack trace: Nessuna pila di errori disponibile
onConnectFailure;Connessione MQTT non riuscita (5): AMQJS0005E Errore interno. Messaggio di errore: Trovati 231 byte extra nel buffer[1], Stack trace: No Error Stack Available
Codifica per il fallback a JSON
Paho non ci dà accesso ai dati del messaggio stesso che ha nelle sue strutture (vedere Codice Paho qui).
Quindi possiamo ripiegare sulla cattura delle eccezioni, assumendo che il messaggio sarà molto probabilmente nel formato MsgPack, e se la decodifica fallisce, passerà a JSON.
E se la decodifica di JSON fallisce, forniamo un fallback {} contro il fuzzing:
extractMessage(message){
// 20.7.2020: passare a msgPack; deve essere payloadBytes, non payloadString
var decodificatoMessaggio = {};
prova {
decodificatoMessaggio = decode(message.payloadBytes);
}
catch (e){
console.log("decode error caught ");
console.log(e);
prova {
decodificatoMessaggio = JSON.parse(message.payloadString);
}
catch (e){
console.log("messaggio malformato (né JSON né MsgPack) - interpretato come oggetto vuoto {}");
}
}
return decodedMessage;
// return JSON.parse(message.payloadString);
}
- si noti che usiamo payloadBytes per accedere al messaggio per msgPack, e payloadString per la decodifica JSON
- notate che la decodifica (e la codifica) sono incluse in questo modo: import { encode, decode } da "@msgpack/msgpack"; nel mio flusso di lavoro Webpack
Riferimenti
- MessagePack (msgpack.org)
- libreria JavaScript msgpack (usa questo invece di quello linkato su msgpack.org, perché ha attività più recenti)
- Codice sorgente Paho MQTT JS
- Documentazione di Paho MQTT JS per il messaggio di classe