简体   繁体   English

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

[英]Sending compressed text over Amazon SQS from PHP to NodeJS

I seem to be stuck at sending the compressed messages from PHP to NodeJS over Amazon SQS. 我似乎停留在通过Amazon SQS将压缩消息从PHP发送到NodeJS。

Over on the PHP side I have: 在PHP方面,我有:

$SQS->sendMessage(Array(
    'QueueUrl'    => $queueUrl,
    'MessageBody' => 'article',
    'MessageAttributes' => Array(
        'json' => Array(
            'BinaryValue' => bzcompress(json_encode(Array('type'=>'article','data'=>$vijest))),
            'DataType' => 'Binary'
        )
    )
));

NOTE 1: I also tried putting compressed data directly in the message, but the library gave me an error with some invalid byte data 注1:我也尝试将压缩数据直接放在消息中,但是库给了我一些错误的字节数据

On the Node side, I have: 在节点方面,我有:

body = decodeBzip(message.MessageAttributes.json.BinaryValue);

Where message is from sqs.receiveMessage() call and that part works since it worked for raw (uncompressed messages) 消息来自sqs.receiveMessage()调用,该部分有效,因为它适用于原始(未压缩的消息)

What I am getting is TypeError: improper format 我得到的是TypeError:格式不正确

I also tried using: 我也试过用:

PHP - NODE PHP - NODE

gzcompress() - zlib.inflateraw() gzcompress() - zlib.inflateraw()

gzdeflate() - zlib.inflate() gzdeflate() - zlib.inflate()

gzencode() - zlib.gunzip() gzencode() - zlib.gunzip()

And each of those pairs gave me their version of the same error (essentially, input data is wrong) 而这些对中的每一对都给了我相同错误的版本(实质上,输入数据是错误的)

Given all that I started to suspect that an error is somewhere in message transmission 考虑到所有这些,我开始怀疑错误是在消息传输中的某个地方

What am I doing wrong? 我究竟做错了什么?

EDIT 1 : It seems that the error is somewhere in transmission, since bin2hex() in php and .toString('hex') in Node return totally different values. 编辑1 :似乎错误在传输中的某个地方,因为php中的bin2hex()和Node中的.toString('hex')返回完全不同的值。 It seems that Amazon SQS API in PHP transfers BinaryAttribute using base64 but Node fails to decode it. 似乎PHP中的Amazon SQS API使用base64传输BinaryAttribute但Node无法对其进行解码。 I managed to partially decode it by turning off automatic conversion in amazon aws config file and then manually decoding base64 in node but it still was not able to decode it. 我设法通过关闭amazon aws配置文件中的自动转换然后手动解码节点中的base64来部分解码它,但它仍然无法解码它。

EDIT 2 : I managed to accomplish the same thing by using base64_encode() on the php side, and sending the base64 as a messageBody (not using MessageAttributes). 编辑2 :我设法通过在php端使用base64_encode()并将base64作为messageBody发送(不使用MessageAttributes)来完成同样的事情。 On the node side I used new Buffer(messageBody,'base64') and then decodeBzip on that. 在节点方面,我使用了新的Buffer(messageBody,'base64'),然后使用decodeBzip。 It all works but I would still like to know why MessageAttribute is not working as it should. 这一切都有效,但我仍然想知道为什么MessageAttribute不能正常工作。 Current base64 adds overhead and I like to use the services as they are intended, not by work arounds. 当前的base64增加了开销,我喜欢按照预期使用服务,而不是通过解决方法。

This is what all the SQS libraries do under the hood. 就是所有SQS库所做的事情。 You can get the php source code of the SQS library and see for yourself. 您可以获取SQS库的php源代码并亲自查看。 Binary data will always be base64 encoded (when using MessageAttributes or not, does not matter) as a way to satisfy the API requirement of having form-url-encoded messages. 二进制数据将始终是base64编码(当使用或不使用MessageAttributes时,无关紧要)作为满足具有form-url编码消息的API要求的方式。

I do not know how long the data in your $vijest is, but I am willing to bet that after zipping and then base64 encoding it will be bigger than before. 我不知道你的$ vijest中的数据有多长,但我愿意打赌,在压缩然后base64编码之后它会比以前更大。

So my answer to you would be two parts (plus a third if you are really stubborn): 所以我对你的回答将是两个部分(如果你真的很顽固,还有三分之一):

  • When looking at the underlying raw API it is absolutely clear that not using MessageAttributes does NOT add additional overhead from base64. 在查看底层原始API时,绝对清楚的是,不使用MessageAttributes不会增加base64的额外开销。 Instead, using MessageAttributes adds some slight additional overhead because of the structure of the data enforced by the SQS php library. 相反,由于SQS php库强制执行的数据结构,使用MessageAttributes会增加一些额外的开销。 So not using MessageAttributes is clearly NOT a workaround and you should do it if you want to zip the data yourself and you got it to work that way. 因此,不使用MessageAttributes显然不是一种解决方法,如果您想自己压缩数据并且让它以这种方式工作,您应该这样做。
  • Because of the nature of a http POST request it is a very bad idea to compress your data inside your application. 由于http POST请求的性质,在应用程序内压缩数据是一个非常糟糕的主意。 Base64 overhead will likely nullify the compression advantage and you are probably better off sending plain text. Base64开销可能会使压缩优势无效,您可能最好不要发送纯文本。
  • If you absolutely do not believe me or the API spec or the HTTP spec and want to proceed, then I would advise to send a simple short string 'teststring' in the BinaryValue parameter and compare what you sent with what you got. 如果你绝对不相信我或API规范或HTTP规范并希望继续,那么我建议在BinaryValue参数中发送一个简单的短字符串'teststring',并将你发送的内容与你得到的内容进行比较。 That will make it very easy to understand the transformations the SQS library is doing on the BinaryValue parameter. 这将使SQS库对BinaryValue参数的转换变得非常容易理解。

gzcompress() would be decoded by zlib.Inflate() . gzcompress()将由zlib.Inflate()解码。 gzdeflate() would be decoded by zlib.InflateRaw() . gzdeflate()将通过解码zlib.InflateRaw() gzencode() would be decoded by zlib.Gunzip() . gzencode()将通过解码zlib.Gunzip() So out of the three you listed, two are wrong, but one should work. 所以在你列出的三个中,有两个是错的,但是一个应该有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM