ServiceStack.Redis:配置为使请求和响应类/ dto是同一类?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ServiceStack.Redis:配置为使请求和响应类/ dto是同一类?相关的知识,希望对你有一定的参考价值。
我已经使用ServiceStack一段时间了,我很了解首选的基于消息的API设计,这是我在一些基于REST的API中使用的东西。
我现在正在研究Redis / MQ库,并且一如既往地享受ServiceStack的结构和功能。但是,我正在研究用MQ服务器替换一些旧的通信代码,并使用tested out some SS examples,并且效果很好。
[但是,我正在使用的一些旧代码使用相同的类来处理传出请求和响应,因此发送了GetSomething
,而答复是GetSomething
相同类的实例,但是具有类似[ C0],其中包含回复/结果。
由于我想直接替换当前的通信模型,所以我想看看这种情况是否可以“即开即用”地得到支持,但是我并没有真正找到解决该问题的方法。当我在具有Handler的Consumer中这样的事情时:
GetSomething.Result
和想要答复的发布者:
mqHost.RegisterHandler<GetSomething>(base.ExecuteMessage);
发生的情况是,发布者立即收到请求,但从未收到消费者。如果我在发布服务器中删除答复的侦听器,它将到达使用者,但是当使用者随后使用相同的DTO mqServer.RegisterHandler<GetSomething>(m => ...);
进行答复时,它将陷入一个永恒的循环,因为我认为答复放置在相同的位置。 MQ队列。
是否有使用ServiceStack解决此问题的明智方法?
我对可能的解决方法有一些想法,但我想知道是否可以通过更好和更聪明的方式解决。
我只是想分享一个解决方法,它可能不是最漂亮的,但似乎可以解决。我仍然对是否有更好的方法感兴趣。
发布者:
发布者将请求过滤器分配给RedisMqServer,然后用该方法修改GetSomething
,用实际请求替换包装器。
然后,发布者为响应包装器类调用一次.Body
,然后为预期的每个实际/实际Handler调用.RegisterHandler
。这将导致调用正确的服务处理程序:
public RedisClient(string name)
Name = name;
redisFactory = new PooledRedisClientManager("localhost:6379");
mqServer = new RedisMqServer(redisFactory, retryCount: 2);
mqServer.RequestFilter = RequestFilter;
// Response wrapper, ContainerResponse implements IProtocolContainer
mqServer.RegisterHandler<ContainerResponse>(m =>
return m;
);
mqServer.RegisterHandler<GetSomething>(m =>
// m.Body is here an GetSomething
return null;
);
mqServer.Start();
private ServiceStack.Messaging.IMessage RequestFilter(ServiceStack.Messaging.IMessage message)
if (message.Body is IProtocolContainer protocolContainer)
message.Body = protocolContainer.TheRequest;
return message;
public void AddMessage<T>(T theRequest) where T : CoreRequest
using (var mqClient = mqServer.CreateMessageQueueClient())
mqClient.Publish(new ContainerRequest(theRequest));
消费者:
相同的原则适用于消费者:
public override void Configure(Container container)
container.Register(new ConsumerInfo() Name = ServiceName );
var redisFactory = new PooledRedisClientManager("localhost:6379");
container.Register<IRedisClientsManager>(redisFactory);
var mqHost = new RedisMqServer(redisFactory, retryCount: 2);
mqHost.RequestFilter = RequestFilter;
mqHost.ResponseFilter = ResponseFilter;
mqHost.RegisterHandler<ContainerRequest>(base.ExecuteMessage);
mqHost.RegisterHandler<GetSomething>(base.ExecuteMessage);
mqHost.Start();
private object ResponseFilter(object arg)
return new ContainerResponse(arg as CoreRequest);
private ServiceStack.Messaging.IMessage RequestFilter(ServiceStack.Messaging.IMessage message)
if (message.Body is IProtocolContainer protocolContainer)
System.Diagnostics.Debug.WriteLine($"\tReplaced Body with protocolContainer.TheRequest.GetType().Name");
message.Body = protocolContainer.TheRequest;
return message;
ServiceStack MQ Message Workflow在文档中定义:
并说明何时会发生什么:
Messages with no responses are sent to ‘.outq’ Topic
Messages with Responses are published to the Response .inq
因此,返回请求DTO会将其放入该请求DTO的INQ中,该请求DTO将由为处理该请求而注册的处理程序执行,在这种情况下恰好是它本身,因此是循环。在Redis MQ Services中,返回null
或void
将其发布到Redis的瞬态/滚动响应DTO .outq。
以上是关于ServiceStack.Redis:配置为使请求和响应类/ dto是同一类?的主要内容,如果未能解决你的问题,请参考以下文章
ServiceStack.Redis 请求次数6000次异常
ServiceStack.Redis:PooledRedisClientManager和RedisManagerPool等待上一请求完成
哪个 Canoe 版本与链接中为 REDIS 客户端实现提供的 soln 兼容 https://github.com/ServiceStack/ServiceStack.Redis