我似乎无法通过 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:我也试过将压缩数据直接放在消息中,但是库给了我一些无效字节数据的错误
在 Node 端,我有:
body = decodeBzip(message.MessageAttributes.json.BinaryValue);
消息来自 sqs.receiveMessage() 调用并且该部分有效,因为它适用于原始(未压缩的消息)
我得到的是类型错误:格式不正确
我也试过使用:
PHP - NODE
gzcompress() - zlib.inflateraw()
gzdeflate() - zlib.inflate()
gzencode() - zlib.gunzip()
每一对都给了我他们对相同错误的版本(本质上,输入数据是错误的)
考虑到所有这些,我开始怀疑消息传输中的某处存在错误
我做错了什么?
编辑 1:似乎错误出在传输的某个地方,因为 php 中的 bin2hex() 和 Node 中的 .toString('hex') 返回完全不同的值。 PHP 中的 Amazon SQS API 似乎使用 base64 传输 BinaryAttribute,但 Node 无法对其进行解码。我设法通过关闭 amazon aws 配置文件中的自动转换,然后在 Node 中手动解码 base64 来部分解码它,但它仍然无法解码。
编辑 2:我设法通过在 php 端使用 base64_encode() 并将 base64 作为 messageBody 发送(不使用 MessageAttributes)来完成同样的事情。在 Node 端,我使用了 new Buffer(messageBody,'base64') 然后在其上使用了 decodeBzip。一切正常,但我仍然想知道为什么 MessageAttribute 不能正常工作。当前的 base64 增加了开销,我喜欢按预期使用服务,而不是变通。
最佳答案
This是所有 SQS 库在幕后所做的事情。大家可以拿到SQS库的php源码自己看看。二进制数据将始终进行 base64 编码(无论是否使用 MessageAttributes 都无关紧要)作为满足具有 form-url 编码消息的 API 要求的一种方式。
我不知道你的 $vijest 中的数据有多长,但我敢打赌,在压缩和 base64 编码之后,它会比以前更大。
所以我对你的回答分为两部分(如果你真的很固执,再加上第三部分):
- 在查看底层原始 API 时,绝对清楚不使用 MessageAttributes 不会增加 base64 的额外开销。相反,由于 SQS php 库强制执行的数据结构,使用 MessageAttributes 会增加一些额外的开销。因此,不使用 MessageAttributes 显然不是一种解决方法,如果您想自己压缩数据并使其以这种方式工作,您应该这样做。
- 由于 http POST 请求的性质,在您的应用程序中压缩您的数据是一个非常糟糕的主意。 Base64 开销可能会抵消压缩优势,您最好发送纯文本。
- 如果您绝对不相信我或 API 规范或 HTTP 规范并想继续,那么我会建议在 BinaryValue 参数中发送一个简单的短字符串“teststring”,并将您发送的内容与您收到的内容进行比较。这将使理解 SQS 库对 BinaryValue 参数所做的转换变得非常容易。
关于php - 通过 Amazon SQS 从 PHP 向 NodeJS 发送压缩文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35844377/