Шина EasynetQ. Подписка не срабатывает - выдаваемый тип сообщения не должен быть нулевым

Я могу успешно опубликовать сообщение со следующим кодом:

        using (IAdvancedBus bus = RabbitHutch.CreateBus("host=192.168.153.128:5672;username=user;password=pass").Advanced)
        {
            IExchange exchange = bus.ExchangeDeclare("milk.api", ExchangeType.Topic);
            IQueue queue = bus.QueueDeclare("milkorderqueue");
            IBinding binding = bus.Bind(exchange, queue, "#");
            bus.Publish<MilkOrderRequest>(exchange, "#", true, new Message<MilkOrderRequest>(milkOrder));
        }
        return new HttpResponseMessage(System.Net.HttpStatusCode.OK);

Когда мой подписчик пытается получить сообщение, очередь EasyNetQ_Default_Error_Queue увеличивается. Вот код для слушателя:

        IBus bus = RabbitHutch.CreateBus(@"host=192.168.153.128:5672;username=user;password=pass");
        bus.Subscribe<MilkOrderRequest>("my_subscription_id", message =>
        {
            Console.WriteLine($"Order recieved: {message.Milk}.");
        }, config =>
        {
            config.WithQueueName("milkorderqueue");
        });

Я также безуспешно пробовал следующее:

        IAdvancedBus bus = RabbitHutch.CreateBus(@"host=192.168.153.128:5672;username=user;password=pass").Advanced;
        IExchange exchange = bus.ExchangeDeclare("milkshop.subscriber", ExchangeType.Topic);
        IQueue queue = bus.QueueDeclare("milkorderqueue");
        bus.Bind(exchange, queue, "#");
        bus.Consume<MilkOrderRequest>(queue, (message, info) =>
        {
            Console.WriteLine($"Order recieved: {message.Body.Milk}.");
        });

У меня возникли проблемы с поиском ответов в Google об исключении:

тип сообщения не должен быть нулевым

Вот полное сообщение:

{
   "RoutingKey":"#",
   "Exchange":"milk.api",
   "Queue":"milkorderqueue",
   "Exception":"System.AggregateException: One or more errors occurred. (messageType must not be null\r\nParameter name: messageType) ---> System.ArgumentNullException: messageType must not be null\r\nParameter name: messageType\r\n   at EasyNetQ.Preconditions.CheckNotNull[T](T value, String name, String message)\r\n   at EasyNetQ.Preconditions.CheckNotNull[T](T value, String name)\r\n   at EasyNetQ.MessageFactory.CreateInstance(Type messageType, Object body, MessageProperties properties)\r\n   at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass17_0.<Consume>b__0(Byte[] body, MessageProperties properties, MessageReceivedInfo messageReceivedInfo)\r\n   at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecutionContext context)\r\n   --- End of inner exception stack trace ---\r\n---> (Inner Exception #0) System.ArgumentNullException: messageType must not be null\r\nParameter name: messageType\r\n   at EasyNetQ.Preconditions.CheckNotNull[T](T value, String name, String message)\r\n   at EasyNetQ.Preconditions.CheckNotNull[T](T value, String name)\r\n   at EasyNetQ.MessageFactory.CreateInstance(Type messageType, Object body, MessageProperties properties)\r\n   at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass17_0.<Consume>b__0(Byte[] body, MessageProperties properties, MessageReceivedInfo messageReceivedInfo)\r\n   at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecutionContext context)<---\r\n",
   "Message":"{\"Milk\":\"semi-skimmed\"}",
   "DateTime":"2018-06-01T11:01:11.645241Z",
   "BasicProperties":{
      "ContentType":null,
      "ContentEncoding":null,
      "Headers":{

      },
      "DeliveryMode":0,
      "Priority":0,
      "CorrelationId":"fe1561c1-4c7c-4489-857e-b664f27a5e5f",
      "ReplyTo":null,
      "Expiration":null,
      "MessageId":null,
      "Timestamp":0,
      "Type":"Milkshop.Common.MilkOrderRequest:Milkshop.Common",
      "UserId":null,
      "AppId":null,
      "ClusterId":null,
      "ContentTypePresent":false,
      "ContentEncodingPresent":false,
      "HeadersPresent":true,
      "DeliveryModePresent":false,
      "PriorityPresent":false,
      "CorrelationIdPresent":true,
      "ReplyToPresent":false,
      "ExpirationPresent":false,
      "MessageIdPresent":false,
      "TimestampPresent":false,
      "TypePresent":true,
      "UserIdPresent":false,
      "AppIdPresent":false,
      "ClusterIdPresent":false
   }
}

Я использую EasynetQ версии 3.0.0 в приложениях .Net Core.


person Noobie3001    schedule 01.06.2018    source источник


Ответы (4)


Нашел ошибку. Мой проект API и консольное приложение использовали разные версии пакета EasynetQ nuget. Один был 2.33, а другой 3.0.0.

person Noobie3001    schedule 01.06.2018

Я не знаю, сталкиваетесь ли вы с этой проблемой, я обнаружил, что борюсь с ней по крайней мере 3 дня, похоже, это проблема с DefaultMessageSerializationStrategy для Netcore2. Я смог исправить, используя эти пользовательские классы, которые я нашел в Интернете:

  • JsonSerializer (реализует: ISerializer)
  • TypeNameSerializer (реализует: ITypeNameSerializer)

Наконец, вы можете создать свой собственный экземпляр DefaultMessageSerializationStrategy и использовать DI:

r.Register<IMessageSerializationStrategy>(new DefaultMessageSerializationStrategy(new TypeNameSerializer(), new MyJsonSerializer(new TypeNameSerializer()), new DefaultCorrelationIdGenerationStrategy()));

Это не лучшее решение, но помогло :D PD: У меня нет ссылок, которые ведут меня к вышеприведенным реализациям, но вы наверняка найдете их с помощью пары поисков в Интернете.

person Enrique Ramos    schedule 14.09.2018

У меня та же проблема, но в моем случае я пытался опубликовать сообщение в консоли управления RabbitMQ и использовать его в своем приложении. Это не работает.

Попробуйте создать другое приложение (я использовал другой метод для имитации публикации в том же приложении) с той же версией EasyNetQ и вместо этого используйте метод публикации.

person Allan Zeidler    schedule 15.04.2020

В моем случае проблема была связана со службой издателя, использующей более старую версию ENQ, которая, в свою очередь, использовала LegacyTypeNameSerializer. На стороне потребляющей службы, которая использовала более новую версию ENQ, все, что мне нужно было сделать, это добавить следующее при создании шины:

serviceRegister.EnableLegacyTypeNaming();

Это метод расширения, который должен быть включен в новые версии ENQ.

person TheRock    schedule 09.04.2021