Request/Reply 说明
Request/Reply explanation
我想了解 request/reply 模式是如何在 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 - winservice hosts the service
public class HelloService : Service
{
public object Any(Hello req)
{
return new HelloResponse
{
Result = req.Id
};
}
}
由于webapi/WebRequestService收到多个并发请求,如何实现"mqClient.Get"在Publish调用后收到相关Hello Request发出的响应?换句话说,在这个虚拟样本中,我如何确定 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);
如果您想获得与特定请求相关的响应,您需要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
,这些进程通常可以处理任何响应,即在每个请求完成后执行任何额外的处理。
我想了解 request/reply 模式是如何在 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 - winservice hosts the service
public class HelloService : Service
{
public object Any(Hello req)
{
return new HelloResponse
{
Result = req.Id
};
}
}
由于webapi/WebRequestService收到多个并发请求,如何实现"mqClient.Get"在Publish调用后收到相关Hello Request发出的响应?换句话说,在这个虚拟样本中,我如何确定 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);
如果您想获得与特定请求相关的响应,您需要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
,这些进程通常可以处理任何响应,即在每个请求完成后执行任何额外的处理。