servicestack 使用ServiceStack广播rabbitMq消息
有没有办法使方法更简单servicestack 使用ServiceStack广播rabbitMq消息,servicestack,rabbitmq,servicestack,Rabbitmq,有没有办法使方法更简单 myMessageService.CreateMessageQueueClient().Publish(myMessage); 将消息广播给所有接收者?问题是,RegisterHandler在内部使用T类型来构建它侦听的队列名称。因此,您唯一的机会就是通过使用自定义扇出交换到多个队列来脱离以下解决方案: var fanoutExchangeName = string.Concat(QueueNames.Exchange,
myMessageService.CreateMessageQueueClient().Publish(myMessage);
将消息广播给所有接收者?问题是,
RegisterHandler
在内部使用T
类型来构建它侦听的队列名称。因此,您唯一的机会就是通过使用自定义扇出交换到多个队列来脱离以下解决方案:
var fanoutExchangeName = string.Concat(QueueNames.Exchange,
".",
ExchangeType.Fanout);
在系统的某一点上,您必须确保使用以下代码进行交换:
var rabbitMqServer = new RabbitMqServer();
var messageProducer = (RabbitMqProducer) rabbitMqServer.CreateMessageProducer();
var channel = messageProducer.Channel; // you can use any logic to acquire a channel here - this is just a demo
channel.ExchangeDeclare(fanoutExchangeName,
ExchangeType.Fanout,
durable: true,
autoDelete: false,
arguments: null);
现在我们可以将消息发布到此扇出:
var message = new Message<T>(yourInstance);
messageProducer.Publish(QueueNames<T>.In, // routing key
message, // message
fanoutExchangeName); // exchange
var message=新消息(yourInstance);
messageProducer.Publish(QueueNames.In,//路由密钥
message,//message
fanoutExchangeName);//交换
因此,现在消息将发布到我们的exchange,但我们需要将队列绑定到消费组件中的exchange,这是我们使用的:
var rabbitMqServer = new RabbitMqServer();
var messageQueueClient = (RabbitMqQueueClient) rabbitMqServer.CreateMessageQueueClient();
var channel = messageQueueClient.Channel; // you just need to get the channel
var queueName = messageQueueClient.GetTempQueueName();
channel.QueueBind(queueName, // queue
fanoutExchangeName, // exchange
QueueName<T>.In); // routing key
var rabbitMqServer=new rabbitMqServer();
var messageQueueClient=(RabbitMqQueueClient)rabbitMqServer.CreateMessageQueueClient();
var channel=messageQueueClient.channel;//你只需要拿到频道就行了
var queueName=messageQueueClient.GetTempQueueName();
channel.QueueBind(queueName,//队列
fanoutExchangeName,//交换
QueueName.In);//路由密钥
在最后一个(也是唯一一个)使用者断开连接后,队列将自动删除,并且在RabbitMq重新启动后将无法生存
不过,现在最让人讨厌的部分是倾听
var consumer = new RabbitMqBasicConsumer(channel);
channel.BasicConsume(queueName,
false,
consumer);
Task.Run(() =>
{
while (true)
{
BasicGetResult basicGetResult;
try
{
basicGetResult = consumer.Queue.Dequeue();
}
catch (EndOfStreamException endOfStreamException)
{
// this is ok
return;
}
catch (OperationInterruptedException operationInterruptedException)
{
// this is ok
return;
}
catch (Exception ex)
{
throw;
}
var message = basicGetResult.ToMessage<T>();
// TODO processing
}
});
var consumer=新RabbitMqBasicConsumer(通道);
channel.BasicConsume(队列名称,
假,,
消费者);
Task.Run(()=>
{
while(true)
{
BasicGetResult BasicGetResult;
尝试
{
basicGetResult=consumer.Queue.Dequeue();
}
catch(EndOfStreamException EndOfStreamException)
{
//这没关系
返回;
}
捕捉(操作中断异常操作中断异常)
{
//这没关系
返回;
}
捕获(例外情况除外)
{
投掷;
}
var message=basicGetResult.ToMessage();
//待办事项处理
}
});
但该解决方案不提供任何自动重新连接、过滤器或其他功能
基本演练如下所示
编辑:
我想到的一件事是:您可以使用
ServiceStack.Messaging.MessageHandler
实例轻松地提供回复和重试。哇,感谢您提供了完整的答案。我几乎已经忘记了最初的问题是什么,但如果我没有弄错的话,我只是手动调整了RabbitMq配置,以实现我的目的。@VictorSuzdalev您是绝对受欢迎的!我觉得这个问题(因为它很常见)应该在ServiceStack中的封装解决方案中解决……ServiceStack的RabbitMQ配置代码非常简单,所以我认为PR会受到欢迎!))@事实上,我添加了一个公关: