Rebus Azure ServiceBus - Липсва ИД на съобщение за съобщение, произхождащо от външна услуга

Създавам доказателство за концепция, използвайки Rebus във връзка с Azure Service Bus, но имам малък проблем с анализирането на съобщение, което е поставено на опашката от външен източник.

Получавам съобщение за грешка:

Получено съобщение с празен или липсващ хедър „rbs2-msg-id“!

Прегледах GitHub и забелязах този списък за това как някой е имал подобен проблем за RabbitMQ и беше препоръчано да се използва декоратор:

https://github.com/rebus-org/Rebus/issues/508

Въпреки това не съм сигурен как да направя това само за ID на съобщението.

Една опция, която бях избрал, всъщност беше промяна на кода на Rebus.AzureTransport, за да направи това:

var messageId = headers.GetValueOrNull(Headers.MessageId);

if (string.IsNullOrEmpty(messageId))
{
    messageId = Guid.NewGuid().ToString();
    headers[Headers.MessageId] = messageId;
}

Но бих предпочел алтернатива!

Друго нещо, което забелязах, е, че BrokeredMessage се поставя на ASB по следния начин:

var message = new BrokeredMessage("<xml>This is a test message: " + DateTime.Now+ "</xml>");

Не се сериализира правилно, когато се получава от Rebus. Получавам следната грешка:

Необработено изключение 1 при обработка на съобщение с ID db13880d-124c-4ed5-993e-96faeca0f140: System.Collections.Generic.KeyNotFoundException: Не може да се намери ключът „rbs2-content-type“

Чрез замяна на сериализатора, основното съобщение се среща като:

@strin3http://schemas.microsoft.com/2003/10/Serialization/?6Това е тестово съобщение: 06/12/2016 07:44:21

така че не съм сигурен какво правя погрешно.

Благодаря предварително.


person jazzyuk    schedule 06.12.2016    source източник


Отговори (1)


Ами... както се казва в съобщенията за грешка, входящото съобщение не съдържа достатъчно информация, за да може Rebus да го обработи.

Освен това транспортът на Azure Service Bus на Rebus изисква съдържанието на съобщението да бъде изпратено като Stream, за да се избегнат разходите за затваряне на съдържащите се байтове в XML структура (което прави драйверът на Azure Service Bus по подразбиране).

Ако бях на ваше място, вероятно нямаше да използвам Rebus за получаване на съобщения от опашка, която не съдържа съобщения, изпратени от Rebus. Или може да го направя – но само ако входящите съобщения са много лесни за адаптиране, за да се придържат към формата на Rebus.

Въпреки това може да е малко тромаво да се случи това, защото – както правилно отбелязахте – изисква наличието на определени заглавки, които функционират като подсказки към Rebus как да го проследява между опитите за обработка, как да го десериализира, къде да отговоря, ако bus.Reply бъде извикан и т.н. Така че все пак може да се окаже, че не го правя така или иначе :)

Предлагам ви да направите нещо подобно:

while(true)
{
    var message = GetNextMessageOrNullFromQueue();

    if (message == null) continue;

    UnwrapMessageAndSendWithRebusToRebusQueue(message);
}

по този начин кодирайте своя собствен цикъл на получаване, за да получавате персонализираните си съобщения на Azure Service Bus, като делегирате действителната обработка на тях (евентуално също десериализация от XML текст в обекти?) на крайна точка на Rebus.

Това обикновено е предпочитаният начин за интегриране с външни неща, защото запазва логиката на свързване напред и назад между външната и вътрешната страна на вашето приложение в периметъра, вместо да прониква във вашето приложение.

person mookid8000    schedule 06.12.2016
comment
Здравейте, благодаря за отговора. Ще разгледам възможността да направя приемния цикъл. Едно нещо, за което не бях сигурен, защо съобщението ще бъде взето неправилно от опашката, когато отменя сериализатора (използвах Utf8Fallback сериализатора във вашия пример за ReceiveNonRebusMessageWithRabbitMq). Бих си помислил, че ще бъде анализиран правилно? - person jazzyuk; 06.12.2016
comment
намери ли отговора? каква е препоръката от 2021 г.? - person Maulik Modi; 17.07.2021
comment
Същата препоръка: Получавайте персонализирани форматирани съобщения на Azure Service Bus в специален цикъл за получаване, използвайте Rebus еднопосочен клиент, за да го препратите като правилно Rebus съобщение към Rebus опашката. - person mookid8000; 17.07.2021