8

只是了解消息队列和 Redis MQ,优秀的框架。

我知道您必须使用 .RegisterHandler(...) 来确定哪个处理程序将处理消息队列中的消息/事件类型。

因此,如果我有 EventA、EventB 等,我应该有一个服务来处理这些事件中的每一个,例如:

public class DomainService : Service {

    public object Any(EventA eventA) {...}
    public object Any(EventB eventA) {...}
}

那么这些应该只是创建的队列/redis列表吗?

另外,如果我希望发生一系列事件,例如 EventA 类型的消息也有一个处理程序,该处理程序发送一封电子邮件,提供链上较早的处理程序成功,该怎么办?

4

1 回答 1

15

ServiceStack在为 MQ、REST、HTML 或 SOAP 服务创建的服务之间没有区别,它们是同一个东西。即它们每个都接受一个请求 DTO 并可选择返回一个响应 DTO,并且同一服务可以处理来自任何端点或格式的调用,例如 HTML、REST、SOAP 或 MQ。

请参阅ServiceStack 的体系结构图以了解 MQ 是如何融入其中的。

限制

您需要记住的唯一事项是:

  • 与 SOAP 一样,MQ 仅支持 1 个动词,因此您的方法需要命名为PostAny
  • 仅执行操作过滤器(即不执行全局或属性过滤器)
  • 您将获得 MqRequest 和 MqResponse 存根来代替IHttpRequest, IHttpResponse。您仍然可以使用.Items通过请求管道传递数据,但任何 HTTP 操作(如设置 cookie 或 HTTP 标头)都是良性的

配置 Redis MQ 主机

MQ 主机本身与 ServiceStack 框架的其余部分完全解耦,在您自己将消息传递到 ServiceStack 之前,谁不知道 MQ 的存在,这通常在您注册的处理程序中完成,例如:

var redisFactory = new PooledRedisClientManager("localhost:6379");
var mqHost = new RedisMqServer(redisFactory, retryCount:2);

mqHost.RegisterHandler<Hello>(m => {
    return this.ServiceController.ExecuteMessage(m);
});

//shorter version:
//mqHost.RegisterHandler<Hello>(ServiceController.ExecuteMessage);


mqHost.Start(); //Starts listening for messages

在你的RegisterHandler<T>你指定你希望它监听的请求类型。

默认情况下,您只能为每条消息注册一个处理程序,并且在 ServiceStack 中,请求与已知的服务实现相关联,在 MQ 的情况下,它正在寻找方法签名首先匹配:Post(Hello)如果不存在,它会查找后备Any(Hello)

可以自己为每条消息添加多个处理程序

如果您想调用多个处理程序,那么您只需维护自己的处理程序,List<Handler>并在请求进入时将它们全部执行并执行。

调用不同的服务

如果您想调用不同的服务,只需将其转换为不同的 Request DTO 并将其传递给 ServiceController。

当任何人发送 MQ 请求时,例如:

mqClient.Publish(new Hello { Name = "Client" });

使用IMessage类型的实例调用您的处理程序,其中 Request DTO 包含在Body属性中。此时,您可以选择丢弃、验证或更改消息。

MQ 请求与任何其他服务请求相同

在大多数情况下,您通常只需将消息转发到ServiceController 以进行处理,其实现是:

public object ExecuteMessage<T>(IMessage<T> mqMsg)
{
    return Execute(mqMsg.Body, new MqRequestContext(this.Resolver, mqMsg));
}

该实现只是从mqMsg.Body中提取 Request DTO并将该消息作为普通服务处理,从那时起通过 C# Request DTO 传递一个包含 MQ IHttpRequest、IHttpResponse 存根的 MqRequestContext。

于 2012-12-13T06:13:10.347 回答