【发布时间】:2016-03-07 12:58:17
【问题描述】:
我似乎无法通过 Amazon SQS 将压缩消息从 PHP 发送到 NodeJS。
在 PHP 方面我有:
$SQS->sendMessage(Array(
'QueueUrl' => $queueUrl,
'MessageBody' => 'article',
'MessageAttributes' => Array(
'json' => Array(
'BinaryValue' => bzcompress(json_encode(Array('type'=>'article','data'=>$vijest))),
'DataType' => 'Binary'
)
)
));
注意 1:我也尝试将压缩数据直接放入消息中,但库给了我一个错误,其中包含一些无效的字节数据
在节点方面,我有:
body = decodeBzip(message.MessageAttributes.json.BinaryValue);
消息来自 sqs.receiveMessage() 调用,并且该部分有效,因为它适用于原始(未压缩的消息)
我得到的是TypeError:格式不正确
我也尝试过使用:
PHP - 节点
gzcompress() - zlib.inflateraw()
gzdeflate() - zlib.inflate()
gzencode() - zlib.gunzip()
每一对都给了我相同错误的版本(本质上,输入数据是错误的)
鉴于我开始怀疑消息传输中的某个错误
我做错了什么?
编辑 1:似乎错误在传输中,因为 php 中的 bin2hex() 和 Node 中的 .toString('hex') 返回完全不同的值。似乎 PHP 中的 Amazon SQS API 使用 base64 传输 BinaryAttribute,但 Node 无法对其进行解码。我设法通过关闭亚马逊aws配置文件中的自动转换然后在节点中手动解码base64来部分解码它,但它仍然无法解码它。
编辑 2:我设法通过在 php 端使用 base64_encode() 并将 base64 作为 messageBody(不使用 MessageAttributes)发送来完成同样的事情。在节点方面,我使用了 new Buffer(messageBody,'base64') 然后 decodeBzip 。一切正常,但我仍然想知道为什么 MessageAttribute 不能正常工作。当前的 base64 增加了开销,我喜欢按预期使用服务,而不是通过变通方法。
【问题讨论】:
-
SQS 基本上是为面向文本的消息而设计的——"Amazon SQS messages can contain up to 256KB of text data"——除非 JSON 编码过程总是巧合地产生有效的 UTF-8 输出,否则我可以理解为什么会有问题。 . base64 编码负载当然会取消压缩的一些好处,因为编码 base-64 会导致 3:4 字节扩展......但仍应导致负载大小的净减少。试试看?
-
是的,但是 SQS 确实有 BinaryAttribute 应该完全用于此目的?他们甚至在他们的文档中说 BinaryAttribute 可用于传输图像、压缩数据等。
-
哦,我明白你在做什么了。公平的问题。我再看看。
-
我会检查从 SQS 收到的原始消息,将在 message.MessageAttributes.json.BinaryValue 中找到的字节与您最初写入的字节进行比较。如果您检查双方的十六进制转储,应该很容易确定它是否被损坏或更改。
-
我希望
bzcompress()的输出以42 5a 68开头,即bzip2 幻数的前三个字节。
标签: php node.js zlib amazon-sqs