以向后兼容的方式从JSON切换到MsgPack,与Paho MQTT(JavaScript)兼容

picockpit.com 大量使用了MQTT。在即将推出的2.0版本中,我决定将其切换到MsgPack。

为什么是MsgPack?

MsgPack(实际上叫 信息包 - 包倾向于使用MsgPack)是一种二进制格式,旨在与JSON兼容,但减少文件大小(这对节省带宽和服务器资源有好处)。

另一个优势。消息包 允许你嵌入二进制数据 (PiCockpit v2.1+有一些令人兴奋的使用案例计划)。

与其他二进制序列化格式(如BSON)相比,MsgPack旨在与JSON更加兼容,更加紧凑。 并可被解码为一个流!

过去保留的信息

由于保留的消息仍然是JSON格式的(还有遗留的客户端仍然在发送JSON消息),然而,需要提供向后的兼容性,特别是在JavaScript方面。

不提供向后兼容将导致Paho的以下问题。

onConnectFailure;MQTT连接失败(5)。AMQJS0005E 内部错误。错误信息。AMQJS0009E 畸形的UTF数据:ad -4f . , 堆栈跟踪。没有可用的错误堆栈

onConnectFailure;MQTT连接失败(5)。AMQJS0005E 内部错误。错误信息。在缓冲区[1]发现额外的231字节,堆栈跟踪。没有可用的错误堆栈

回落到JSON的编码

Paho不允许我们访问它的结构中的消息数据本身(见 这里的Paho代码).

因此,我们可以退回到异常捕捉,假设消息很可能是MsgPack格式,如果解码失败,将切换到JSON。

而如果解码JSON失败,我们提供了一个{}的退路来对抗模糊。

extractMessage(message){
     // 20.7.2020: 切换到msgPack;必须是payloadBytes,而不是payloadString
     var decodedMessage = {};
     试试 {
         decodedMessage = decode(message.payloadBytes);
     }
     catch (e){
         console.log("Decode error caught")。
         console.log(e)。
         试试 {
             decodedMessage = JSON.parse(message.payloadString)。
         }
         catch (e){
             console.log("畸形的信息(既不是JSON也不是MsgPack)--解释为空对象{}")。
         }
     }
     return decodedMessage;
     //返回JSON.parse(message.payloadString)。
}

形象

  • 注意,我们用payloadBytes来访问msgPack的信息,用payloadString来进行JSON解码。
  • 注意,解码(和编码)是这样包括的。 从"@msgpack/msgpack "导入 { encode, decode }。 在我的Webpack工作流程中

参考文献