Servicestack-RabbitMq: вернуть тип ответа в заголовках сообщений

Есть ли способ добавить тип ответа dto в коллекцию заголовков ответного сообщения rabbitmq?

(Мой потребитель использует обработчик Spring rabbitmq, который, кажется, зависит от явной информации о типе внутри заголовка mq при десериализации.)

В настоящее время производитель mq в servicetack уже возвращает несколько заголовков, таких как "content_type='application/json".

Мне нужен дополнительный заголовок, например, "typeId" = "HelloResponse", чтобы веб-приложение-потребитель знало, как десериализовать сообщение, даже в случаях RPC, где имя очереди ответов является своего рода GUID.

Есть ли какая-то конфигурация, которая позволила бы мне архивировать такое поведение? Или какой-нибудь хук перед публикацией сообщения, чтобы я мог сам добавить заголовок?

1 ответ

Решение

Я добавил поддержку автоматического заполнения типа тела сообщения в RabbitMQ IBasicProperties.Type а также добавление поддержки обоих фильтров публикации и GetMessage в этом коммите.

Вот пример настройки RabbitMqServer с пользовательскими обработчиками, где вы можете изменить сообщение и его свойства метаданных при публикации и получении:

string receivedMsgApp = null;
string receivedMsgType = null;

var mqServer = new RabbitMqServer("localhost") 
{
    PublishMessageFilter = (queueName, properties, msg) => {
        properties.AppId = "app:{0}".Fmt(queueName);
    },
    GetMessageFilter = (queueName, basicMsg) => {
        var props = basicMsg.BasicProperties;
        receivedMsgType = props.Type; //automatically added by RabbitMqProducer
        receivedMsgApp = props.AppId;
    }
};

mqServer.RegisterHandler<Hello>(m => 
    new HelloResponse { Result = "Hello, {0}!".Fmt(m.GetBody().Name) });

mqServer.Start();

После настройки любое опубликованное или полученное сообщение пройдет через описанные выше обработчики, например:

using (var mqClient = mqServer.CreateMessageQueueClient())
{
    mqClient.Publish(new Hello { Name = "Bugs Bunny" });
}

receivedMsgApp.Print();   // app:mq:Hello.In
receivedMsgType.Print();  // Hello

using (IConnection connection = mqServer.ConnectionFactory.CreateConnection())
using (IModel channel = connection.CreateModel())
{
    var queueName = QueueNames<HelloResponse>.In;
    channel.RegisterQueue(queueName);

    var basicMsg = channel.BasicGet(queueName, noAck: true);
    var props = basicMsg.BasicProperties;

    props.Type.Print();   // HelloResponse
    props.AppId.Print();  // app:mq:HelloResponse.Inq

    var msg = basicMsg.ToMessage<HelloResponse>();
    msg.GetBody().Result.Print();  // Hello, Bugs Bunny!
}

Это изменение доступно из ServiceStack v4.0.33 +, который теперь доступен на MyGet.

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