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

我似乎被卡在通过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()

而每一对都给了我他们的版本相同的错误(本质上,input数据是错误的)

鉴于所有我开始怀疑在消息传输的某个地方的错误

我究竟做错了什么?

编辑1 :似乎错误是在传输中的某处,因为PHP中的bin2hex()和.toString('hex')在节点返回完全不同的值。 似乎PHP中的Amazon SQS API使用base64传输BinaryAttribute,但Node无法对其进行解码。 我设法通过closures在amazon awsconfiguration文件中的自动转换,然后在节点中手动解码base64,但它仍然无法解码它部分解码。

编辑2 :我设法通过使用base64_encode()在PHP端,并发送base64作为messageBody(不使用MessageAttributes)完成相同的事情。 在节点端,我使用了新的Buffer(messageBody,'base64'),然后使用decodeBzip。 这一切工作,但我仍然想知道为什么MessageAttribute不工作,因为它应该。 目前的base64增加了开销,我喜欢按照他们的意图使用这些服务,而不是通过工作。

这就是所有SQS库在底层所做的事情。 你可以得到SQS库的PHP源代码并亲自体验。 二进制数据将始终是base64编码(当使用MessageAttributes或不使用时,无关紧要),以满足具有form-url-encoded消息的API要求。

我不知道你的$ vijest中的数据有多长,但我敢打赌,压缩后,然后base64编码将比以前更大。

所以我对你的回答是两个部分(如果你真的固执的话,加上三分之一):

  • 当查看底层原始API时,绝对清楚的是,不使用MessageAttributes不会增加来自base64的额外开销。 相反,使用MessageAttributes会增加一些额外的开销,因为SQS php库强制实施的数据结构。 所以不使用MessageAttributes显然不是一个解决方法,你应该这样做,如果你想自己压缩数据,你得到它的工作方式。
  • 由于http POST请求的性质,在应用程序中压缩数据是非常糟糕的主意。 Base64开销可能会使压缩优势无效,并且您可能更好地发送纯文本。
  • 如果你绝对不相信我或API规范或HTTP规范,并且想继续,那么我会build议在BinaryValue参数中发送一个简单的短string“teststring”,并比较你发送的和你得到的。 这将使得理解SQS库在BinaryValue参数上进行的转换变得非常容易。

gzcompress()将被zlib.Inflate()解码。 gzdeflate()将被zlib.InflateRaw()解码。 gzencode()将被zlib.Gunzip()解码。 所以在你列出的三个中,有两个是错的,但是一个应该工作。