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.