ServiceStack makes no difference between the services created for MQ, REST, HTML or SOAP services, they are the same. that is, each of them receives a DTO request and, possibly, returns a DTO of the response, and the same service can process calls from any endpoint or format, such as HTML, REST, SOAP or MQ.
Refer to the ServiceStack Architecture diagram for how MQ fits.
Limitations
The only thing you need to keep in mind:
- Like SOAP, MQ only supports 1 verb, so your methods should be named Publish or Any
- Only Action Filters are executed (i.e. not global or attribute filters)
- Instead of
IHttpRequest , IHttpResponse you get the MqRequest and MqResponse stubs. You can still use .Items to transfer data through the request pipeline, but any HTTP actions, such as setting cookies or HTTP headers, are benign
Redis MQ host setup
The MQ host itself is completely separate from the rest of the ServiceStack infrastructure, which does not know that MQ exists until you pass the message to ServiceStack yourself, which is usually done inside your registered handler, for example:
var redisFactory = new PooledRedisClientManager("localhost:6379"); var mqHost = new RedisMqServer(redisFactory, retryCount:2); mqHost.RegisterHandler<Hello>(m => { return this.ServiceController.ExecuteMessage(m); });
In RegisterHandler<T> you specify the type of request you want to listen to.
By default, you can register only one handler for each message, and in ServiceStack the request is tied to the well-known implementation of Service, in the case of MQ it looks for the first signature of the method: Post(Hello) , and if it is not, t it looks for a backup Any(Hello) .
Can add multiple handlers to a message on its own
If you want to call several handlers, then you just save your own List<Handler> and just execute and execute them all when prompted.
Call various services
If you want to call another service, just translate it into another DTO request and pass it instead of ServiceController.
When an MQ request is sent by someone, for example:
mqClient.Publish(new Hello { Name = "Client" });
Your handler is called with an instance of IMessage type, where the DTO request is contained in the Body property. At this point, you can reject the message, confirm it or change it.
MQ requests are the same as any other service requests
In most cases, you usually just send a message to the ServiceController for processing , the implementation of which:
public object ExecuteMessage<T>(IMessage<T> mqMsg) { return Execute(mqMsg.Body, new MqRequestContext(this.Resolver, mqMsg)); }
The implementation simply retrieves the DTO request from mqMsg.Body and treats this message as a normal service sent from the C # request DTO from now on, with the MqRequestContext that contains the MQ IHttpRequest, IHttpResponse Holes.