mat*_*hat 5 javascript node.js msgpack
我正在使用node-msgpack来编码和解码在机器之间传递的消息.我希望能够做的一件事是将原始缓冲区数据包装在一个对象中并使用Messagepack对其进行编码.
msgpack = require('msgpack')
buf = <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 ...>
obj = {foo: buf}
packed = msgpack.pack(obj)
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我想对嵌套在对象中的缓冲区的原始字节进行一致性检查.所以buf得到如此:
var buf = fs.readFileSync('some_image.png');
Run Code Online (Sandbox Code Playgroud)
在一个完美的世界里,我会得到:
new Buffer(msgpack.unpack(packed).foo);
#> <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 ...>
Run Code Online (Sandbox Code Playgroud)
相反,我最终得到一些随机数.深入挖掘,我最终得到以下好奇心:
enc = 'ascii'
new Buffer(buf.toString(enc), enc)
#> <Buffer *ef bf bd* 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 ...>
buf
#> <Buffer *89* 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 02 00 ...>
Run Code Online (Sandbox Code Playgroud)
第一个字节是问题.我尝试使用不同的编码而没有运气.这里发生了什么,我该怎么办才能绕过这个问题?
最初,这buf是我用msgpack本身生成的缓冲区,因此是双重打包数据.为了避免任何混淆,我将其替换为通过读取图像获得的另一个缓冲区,这引起了同样的问题.
使用除base64和之外的任何编码文本解码二进制数据时,会发生缓冲区损坏问题hex.似乎没有被node-msgpack接收.它似乎会自动尝试使用'utf-8',这会不可逆转地搞砸缓冲区.他们必须做类似的事情,所以我们最终不会得到一堆缓冲对象而不是普通的字符串,这通常是我们的msgpack对象通常由.
编辑:
上面显示的有问题的三个字节代表UTF-8 替换字符.快速测试显示此字符是0x89在开头替换无法识别的字节:
new Buffer((new Buffer('89', 'hex')).toString('utf-8'), 'utf-8')
//> <Buffer ef bf bd>
Run Code Online (Sandbox Code Playgroud)
来自node-msgpack的这一行C++代码负责此行为.当拦截Buffer给予编码器的数据结构中的实例时,它只是将其绑定地转换为a String,相当于执行buffer.toString()默认情况下假设UTF-8编码,用上述代替每个无法识别的字符.
下面建议的替代模块通过将缓冲区保留为原始字节而不是尝试将其转换为字符串来解决此问题,但这样做与其他MessagePack实现不兼容.如果兼容性是一个问题,那么解决这个问题的方法是UTF-8使用二进制安全编码提前编码非缓冲区binary,base64或者hex.base64或hex将不可避免地被一个显著量增长的数据的大小,但会离开它一贯的和最安全的是通过HTTP传输数据时使用.如果大小也是一个问题,那么通过流式压缩算法(如Snappy)来管理MessagePack结果可能是一个不错的选择.
结果是另一个模块,msgpack-js(这是一个用javascript编写的msgpack编码器/解码器),保留原始二进制数据,从而解决了上述问题.他是这样做的:
我将格式扩展了一点,以便对undefined和Buffer实例进行编码和解码.
这需要三个以前标记为"保留"的新类型代码.此更改意味着使用这些新类型将使您的序列化数据与不具有相同扩展名的其他messagepack实现不兼容.
作为奖励,它的性能也比之前提到的基于C++扩展的模块更高效.它也更年轻,所以可能没有经过彻底的测试.时间会证明.这是我做的快速基准测试的结果,基于node-msgpack中包含的基准,比较两个库(以及本机JSON解析器):
node-msgpack pack: 3793 ms
node-msgpack unpack: 1340 ms
msgpack-js pack: 3132 ms
msgpack-js unpack: 983 ms
json pack: 1223 ms
json unpack: 483 ms
Run Code Online (Sandbox Code Playgroud)
因此,虽然我们看到使用本机javascript msgpack解码器的性能改进,但JSON仍然更具性能.
| 归档时间: |
|
| 查看次数: |
2164 次 |
| 最近记录: |