Кажется, я застрял при отправке сжатых сообщений из PHP на NodeJS через Amazon SQS.
На стороне 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 (), и эта часть работает, так как она работает для необработанных (несжатых сообщений)
Что я получаю Ошибка типа: неправильный формат
Я также пытался использовать:
PHP — УЗЕЛ
gzcompress () — zlib.inflateraw ()
gzdeflate () — zlib.inflate ()
gzencode () — zlib.gunzip ()
И каждая из этих пар дала мне свою версию одной и той же ошибки (по сути, входные данные неверны)
Учитывая все это, я начал подозревать, что ошибка находится где-то в передаче сообщения
Что я делаю неправильно?
РЕДАКТИРОВАТЬ 1: Кажется, что ошибка где-то в передаче, поскольку bin2hex () в php и .toString (‘hex’) в Node возвращают совершенно разные значения. Похоже, что API Amazon SQS в PHP передает BinaryAttribute с использованием base64, но Node не может его декодировать. Мне удалось частично декодировать его, отключив автоматическое преобразование в конфигурационном файле amazon aws, а затем вручную расшифровав base64 в узле, но он все равно не смог его декодировать.
РЕДАКТИРОВАТЬ 2Мне удалось сделать то же самое, используя base64_encode () на стороне php и отправив base64 как messageBody (без использования MessageAttributes). На стороне узла я использовал новый Buffer (messageBody, ‘base64’) и затем расшифровал его. Все это работает, но я все еще хотел бы знать, почему MessageAttribute не работает должным образом. Текущий base64 добавляет накладных расходов, и мне нравится использовать сервисы так, как они предназначены, а не обходными путями.
это это то, что все библиотеки SQS делают под капотом. Вы можете получить исходный код php библиотеки SQS и убедиться в этом сами. Двоичные данные будут всегда быть в кодировке base64 (при использовании MessageAttributes или нет, не имеет значения) как способ удовлетворить требование API иметь сообщения в кодировке формы URL.
Я не знаю, как долго будут храниться данные в вашем $ vijest, но я готов поспорить, что после архивирования и последующего кодирования base64 они будут больше, чем раньше.
Поэтому мой ответ вам будет состоять из двух частей (плюс третья, если вы действительно упрямый):
gzcompress()
будет декодирован zlib.Inflate()
, gzdeflate()
будет декодирован zlib.InflateRaw()
, gzencode()
будет декодирован zlib.Gunzip()
, Итак, из трех перечисленных вами два неправильные, но один должен работать.