Использование сообщения очереди Azure в Java с использованием сообщения BrokeredMessage . getBody() перезагружает некоторую информацию заголовка, как от нее избавиться?

Я пытаюсь получить сообщение очереди Azure с Java. Я могу получить сообщение, используя BrokeredMessage в Java. (Я новичок в Java).

Моя проблема в том, что message.getBody() также возвращает некоторую информацию заголовка (не только сообщение, которое мне нужно).

I get     string3http://schemas.mi@string3http://schemas.microsoft.com/2003/10/Serialization/?? message appended with my body in front of it. How can I get rid of this header information.

И я также заметил, что я получаю сообщение в двух партиях. (Не все сразу)

My first batch of message.getBody()returns below message
'@string3http://schemas.mi'
My Second batch of message.getBody()returns below message
@crosoft.com/2003/10/Serialization/?? + My actual message.

Мой общий размер сообщения меньше, чем 500B, но я установил размер байта в 4096. Так что это не ширма из-за проблемы размера.

Это мой код получателя, который я использую.

ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.PEEK_LOCK);

while (true)
{
ReceiveQueueMessageResult resultQM =
service.receiveQueueMessage("MyqueueName", opts);
BrokeredMessage message = resultQM.getValue();
if (message != null && message.getMessageId() != null)
{

byte[] b = new byte[4096];
String s = null;
int numRead = message.getBody().read(b);
while (-1 != numRead)
{
s = new String(b);
s = s.trim();
System.out.print(s);
numRead = message.getBody().read(b);
}
}

}

Это общий вывод System.out.print(s);. (Но в двух партиях, как я упоминал ранее)

total output
string3http://schemas.microsoft.com/2003/10/Serialization/??+ My actual message.

Любая помощь высоко ценится!

2 ответа

Я думаю, что вы получаете вышеупомянутый образец отсюда. Прежде чем приступить к работе с Кодексом, нам необходимо разобраться с типами блокировки режима приема, которые PeekLock а также ReceiveAndDelete

ReceiveAndDelete:

При использовании режима ReceiveAndDelete получение является single-shot operation то есть, когда служебная шина получает запрос на чтение сообщения в очереди, она помечает сообщение как consumed and returns it to the application, Режим ReceiveAndDelete (который является режимом по умолчанию) является самой простой моделью и лучше всего подходит для сценариев, в которых приложение может допустить не обработку сообщения в случае сбоя. Чтобы понять это, рассмотрим сценарий, в котором потребитель выдает запрос на получение, а затем падает перед его обработкой. Поскольку служебная шина пометит сообщение как использованное, то, когда приложение перезапустится и снова начнет использовать сообщения, оно пропустит сообщение, использованное до сбоя.

PeekLook:

В режиме PeekLock получение становится two-stage operation, что позволяет поддерживать приложения, которые не могут терпеть пропущенные сообщения. Когда служебная шина получает запрос, она находит следующее сообщение для использования, locks it to prevent other consumers receiving it, а затем возвращает его в приложение. После того, как приложение завершает обработку сообщения (или надежно сохраняет его для дальнейшей обработки), оно завершает второй этап процесса приема, вызывая Delete для полученного сообщения. Когда служебная шина видит вызов Delete, она помечает сообщение как использованное и удаляет его из очереди.

Вы пытаетесь с режимом PeekLock, в котором вам нужно явно вызвать deleteMessage(message) чтобы пометить сообщение как использованное, если только вы не вызвали этот метод, даже если оно выглядит как использованное, но фактически не использованное. Это все еще в очереди.

Я думаю, что заголовок, который вы упоминаете, не является фактическим заголовком, это было начальное сообщение в очереди, которое фактически не используется вообще.

Вы можете проверить это, как изменить свой код, как показано ниже, и попробовать

if (message != null && message.getMessageId() != null)
{

byte[] b = new byte[4096];
String s = null;
int numRead = message.getBody().read(b);
while (-1 != numRead)
{
s = new String(b);
s = s.trim();
System.out.print(s);
numRead = message.getBody().read(b);
}
//Add the below to ack that you are consumed the message
service.deleteMessage(message);
}    
}

Спасибо, Jayendaran за ваш ответ. Преобразование типа режима из PeekLock в ReceiveAndDelete не решило проблему.

Однако я нашел решение Пропаривание сообщения перед отправкой решает проблему.

Вместо этого

BrokeredMessage message = new BrokeredMessage(encryptData);
message.ContentType = "application/json";
testQueueSender.Send(message);

Сделайте это, чтобы решить проблему

byte[] bytes = Encoding.UTF8.GetBytes(encryptData);
MemoryStream stream = new MemoryStream(bytes, writable: false);
BrokeredMessage message = new BrokeredMessage(stream);
message.ContentType = "application/json";
testQueueSender.Send(message);

Но я все еще получаю сообщение в двух частях по некоторым причинам. первая часть 27 байтов фиксирована все время. Но у меня нет этой проблемы в.NET.

С уважением

Другие вопросы по тегам