请求/回复说明

时间:2015-01-14 15:58:00

标签: servicestack

我试图理解如何在ServiceStack / MQServers中实现模式请求/回复

假设来自wiki

的用例
mqClient.Publish(new Hello { Name = "World" });

var responseMsg = mqClient.Get<HelloResponse>(QueueNames<HelloResponse>.In);
mqClient.Ack(responseMsg);
responseMsg.GetBody().Result //= Hello, World!

让我们说代码片段已经在IIS中托管的Web应用程序中的服务方法中调用

// web api - IIS hosts the service
public class WebRequestService : Service
{
    public IMessageService MessageService { get; set; }

    public object Any(MyWebRequest request)
    {
        using (var mqClient = MessageService.CreateMessageQueueClient())
        {
            var id = Guid.NewGuid().ToString();

            mqClient.Publish(new Hello { Id = id });
            var msgCopy = mqClient.Get<HelloResponse>(QueueNames<HelloResponse>.In);

            mqClient.Ack(msgCopy);
            var response = msgCopy.GetBody();
            Logger.DebugFormat("Request for '{0}' replied '{1}'.", id, response.Result);

        }

        return new MyWebRequestResponse
        {
            Result = "result"
        };
    }
}

Publish方法将Hello请求发送给承载HelloService的middletier

// middletier - winservice hosts the service
public class HelloService : Service
{
    public object Any(Hello req)
    {
        return new HelloResponse
        {
            Result = req.Id
        };
    }
}

由于webapi / WebRequestService接收到多个并发请求,如何在发布调用之后获取&#34; mqClient.Get&#34;,收到由于相关的Hello请求而发出的响应?换句话说,我怎么能确定,在这个虚拟样本中,Hello.Id(通过Publish方法发送)与HelloResponse.Result匹配(通过mqClient.Get接收)? 如何确保与已发布的请求及其回复的相关性? 如何阻止mqClient.Get查看与上一行代码中已发布的消息无关的消息?

我到目前为止唯一的解决方法是使用replyTo选项,以便为每个WebApi请求创建一个队列,但我不认为这是一个选项

var uid = Guid.NewGuid().ToString();
string replyToMq = "mq:Hello.replyto." + uid;
mqClient.Publish(new Message<Hello>( new Hello { Id = id })
{
    ReplyTo = replyToMq
});
var msgCopy = mqClient.Get<HelloResponse>(replyToMq);

1 个答案:

答案 0 :(得分:1)

如果您想获得与特定请求相关的回复,则需要specify a ReplyTo address,例如:

const string replyToMq = mqClient.GetTempQueueName();
mqClient.Publish(new Message<Hello>(new Hello { Name = "World" }) {
    ReplyTo = replyToMq
});

IMessage<HelloResponse> responseMsg = mqClient.Get<HelloResponse>(replyToMq);
mqClient.Ack(responseMsg);
responseMsg.GetBody().Result //= Hello, World!

您不需要为长期运行(无状态)进程指定ReplyTo,这些进程可以一般地处理任何响应,即在每个请求完成后执行任何其他处理。