通过Amazon SQS将压缩文本从PHP发送到NodeJS

Dam*_*vic 5 php zlib amazon-sqs node.js

我似乎停留在通过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'
        )
    )
));
Run Code Online (Sandbox Code Playgroud)

注意1:我也尝试将压缩数据直接放入消息中,但是该库给我一个错误,其中包含一些无效的字节数据

在节点方面,我有:

body = decodeBzip(message.MessageAttributes.json.BinaryValue);
Run Code Online (Sandbox Code Playgroud)

消息来自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无法对其进行解码。我设法通过关闭Amazon aws配置文件中的自动转换,然后在node中手动解码base64来部分解码它,但是它仍然无法解码。

编辑2:通过在php端使用base64_encode(),并将base64作为messageBody发送(不使用MessageAttributes),我设法完成了同样的事情。在节点侧,我使用了新的Buffer(messageBody,'base64'),然后在其上使用了解码Bzip。一切正常,但是我仍然想知道为什么MessageAttribute无法正常工作。当前的base64增加了开销,我喜欢按预期使用服务,而不是通过变通办法。

Fre*_*ags 6

就是所有 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 参数所做的转换变得非常容易。