php - 通过 Amazon SQS 从 PHP 向 NodeJS 发送压缩文本

标签 php node.js zlib amazon-sqs

我似乎无法通过 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/

相关文章:

C zlib 链接错误

php - 如何为 Propel 中的时间戳列指定 defaultValue 为 "now"?

php - 在 MySQL 和 PHP 中查询数据库中的所有表

php - 如何在 OpenCart 2.0.3.1 中从 OpenCart 1.5.6.4 导入产品

php - 使用 MySQL 查询在 PHP 中计算时间

javascript - 为什么 fetch 在我的移动浏览器上不起作用?

javascript - 使用 Promises 从 DynamoDB 异步检索数据

c - 对于任何真实数据集,数据压缩比的最小可能值是多少

c++ - ZLib Inflate() 失败并显示 -3 Z_DATA_ERROR

node.js - 在应用服务器中安装jsreport