ServiceStack não tem distinção entre serviços criados para serviços MQ, REST, HTML ou SOAP, são a mesma coisa. ou seja, cada um deles aceita um DTO de solicitação e, opcionalmente, retorna um DTO de resposta e o mesmo serviço pode manipular chamadas de qualquer terminal ou formato, por exemplo, HTML, REST, SOAP ou MQ.
Consulte o diagrama de arquitetura do ServiceStack para ver como o MQ se encaixa.
Limitações
As únicas coisas que você precisa ter em mente são:
- Assim como o SOAP, os MQs suportam apenas 1 verbo, então seus métodos precisam ser nomeados Post ou Qualquer
- Somente os filtros de ação são executados (ou seja, não os filtros globais ou de atributo)
- Você obtém stubs MqRequest e MqResponse no lugar de
IHttpRequest
,IHttpResponse
. Você ainda pode usar.Items
para passar dados pelo pipeline de solicitação, mas quaisquer ações HTTP, como configurar cookies ou cabeçalhos HTTP, são benignas
Configurando um host Redis MQ
O próprio MQ Host é completamente desacoplado do restante da estrutura do ServiceStack, que não sabe que o MQ existe até que você mesmo passe a mensagem para o ServiceStack, o que geralmente é feito dentro do seu manipulador registrado, por exemplo:
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
Em seu
RegisterHandler<T>
você especifica o tipo de solicitação que deseja ouvir. Por padrão, você só pode registrar um único manipulador para cada mensagem e no ServiceStack uma solicitação está vinculada a uma implementação de serviço conhecida, no caso de MQs está procurando uma assinatura de método primeiro correspondente:
Post(Hello)
e se isso não existir, ele procura o fallback Any(Hello)
. Você mesmo pode adicionar vários manipuladores por mensagem
Se você quiser invocar vários manipuladores, basta manter seu próprio
List<Handler>
e basta passar e executá-los todos quando uma solicitação chegar. Ligar para serviços diferentes
Se você quiser chamar um serviço diferente, apenas traduza-o para um DTO de solicitação diferente e passe-o para o ServiceController.
Quando uma solicitação MQ é enviada por qualquer pessoa, por exemplo:
mqClient.Publish(new Hello { Name = "Client" });
Seu manipulador é invocado com uma instância do tipo IMessage em que o DTO de solicitação está contido no Body propriedade. Nesse ponto, você pode optar por descartar a mensagem, validá-la ou alterá-la.
As solicitações de MQ são iguais a qualquer outra solicitação de serviço
Na maioria dos casos, você normalmente apenas encaminharia a mensagem para o ServiceController para processar, cuja implementação é:
public object ExecuteMessage<T>(IMessage<T> mqMsg)
{
return Execute(mqMsg.Body, new MqRequestContext(this.Resolver, mqMsg));
}
A implementação apenas extrai o Request DTO do mqMsg.Body e processa essa mensagem como um serviço normal sendo passado um C# Request DTO a partir desse ponto, com um MqRequestContext que contém os stubs MQ IHttpRequest, IHttpResponse.