Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Redis:配置请求和响应类/dto为同一类?_C#_Redis_<img Src="//i.stack.imgur.com/WM7S8.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">servicestack - Fatal编程技术网 servicestack,C#,Redis,servicestack" /> servicestack,C#,Redis,servicestack" />

C# Redis:配置请求和响应类/dto为同一类?

C# Redis:配置请求和响应类/dto为同一类?,c#,redis,servicestack,C#,Redis,servicestack,我很久以前就使用过ServiceStack,我很清楚基于消息的API设计是首选,这是我在一些基于REST的API中使用的 我现在正在研究Redis/MQ库,并一如既往地享受ServiceStack的结构和功能。然而,我正在考虑用MQ服务器替换一些遗留通信代码,并且已经完成了,并且工作得很好 但是,我正在使用的一些遗留代码将同一类用于传出请求和响应,因此会发送类似GetSomething,并且回复是同一类GetSomething的实例,但具有类似GetSomething.Result的属性,其中包

我很久以前就使用过ServiceStack,我很清楚基于消息的API设计是首选,这是我在一些基于REST的API中使用的

我现在正在研究Redis/MQ库,并一如既往地享受ServiceStack的结构和功能。然而,我正在考虑用MQ服务器替换一些遗留通信代码,并且已经完成了,并且工作得很好

但是,我正在使用的一些遗留代码将同一类用于传出请求和响应,因此会发送类似
GetSomething
,并且回复是同一类
GetSomething
的实例,但具有类似
GetSomething.Result
的属性,其中包含回复/结果

因为我想替换当前的通信模型,所以我想看看这个场景是否可以“开箱即用”得到支持,但我并没有找到任何解决方法。当我在具有处理程序的消费者中这样做时:

mqHost.RegisterHandler<GetSomething>(base.ExecuteMessage);
mqHost.RegisterHandler(base.ExecuteMessage);
出版商希望得到回复:

mqServer.RegisterHandler<GetSomething>(m => {...});
mqServer.RegisterHandler(m=>{…});
发生的情况是,发布者立即接收请求,而请求从未到达消费者。如果我在发布服务器中删除回复的侦听器,它会到达消费者,但是当消费者使用相同的DTO,
GetSomething
进行回复时,它会陷入一个永恒的循环,因为我认为回复被放置在同一个MQ队列中

有没有一种聪明的方法可以使用ServiceStack解决这个问题


我对可能的解决方法有一些想法,但我想知道是否可以用更好、更聪明的方法解决这个问题。

我只想分享一个解决方法,它可能不是最漂亮的,但似乎很有效。如果有更好的方法,我仍然感兴趣

出版商:

发布者将RequestFilter分配给RedisMqServer,并在该方法中修改
.Body
,用实际请求替换包装器

然后,发布者为响应包装器类调用一次
.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客户端(字符串名称)
{
名称=名称;
redisFactory=new PooledRedisClientManager(“本地主机:6379”);
mqServer=new RedisMqServer(redisFactory,retryCount:2);
mqServer.RequestFilter=RequestFilter;
//响应包装器,ContainerResponse实现IProtocolContainer
mqServer.RegisterHandler(m=>
{
返回m;
});
mqServer.RegisterHandler(m=>
{
//m.Body在这是一个什么东西
返回null;
});
mqServer.Start();
}
私有ServiceStack.Messaging.IMessage请求筛选器(ServiceStack.Messaging.IMessage消息)
{
if(message.Body是IProtocolContainer协议容器)
{
message.Body=protocolContainer.TheRequest;
}
返回消息;
}
公共void AddMessage(T请求),其中T:CoreRequest
{
使用(var mqClient=mqServer.CreateMessageQueueClient())
{
Publish(新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;
    }
}
public override void Configure(容器)
{
Register(new ConsumerInfo(){Name=ServiceName});
var redisFactory=new PooledRedisClientManager(“localhost:6379”);
容器。注册(工厂);
var mqHost=new RedisMqServer(redisFactory,retryCount:2);
mqHost.RequestFilter=RequestFilter;
mqHost.ResponseFilter=ResponseFilter;
mqHost.RegisterHandler(base.ExecuteMessage);
mqHost.RegisterHandler(base.ExecuteMessage);
mqHost.Start();
}
专用对象响应过滤器(对象参数)
{
返回新的ContainerResponse(arg作为CoreRequest);
}
私有ServiceStack.Messaging.IMessage请求筛选器(ServiceStack.Messaging.IMessage消息)
{
if(message.Body是IProtocolContainer协议容器)
{
System.Diagnostics.Debug.WriteLine($“\t用{protocolContainer.TheRequest.GetType().Name}替换正文);
message.Body=protocolContainer.TheRequest;
}
返回消息;
}
}

我只想分享一个解决方案,它可能不是最漂亮的,但似乎很有效。如果有更好的方法,我仍然感兴趣

出版商:

发布者将RequestFilter分配给RedisMqServer,并在该方法中修改
.Body
,用实际请求替换包装器

然后,发布者为响应包装器类调用一次
.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客户端(字符串名称)
{
名称=名称;
redisFactory=new PooledRedisClientManager(“本地主机:6379”);
mqServer=new RedisMqServer(redisFactory,retryCount:2);
mqServer.RequestFilter=RequestFilter;
//响应包装器,ContainerResponse实现IProtocolContainer
mqServer.RegisterHandler(m=>
{
返回m;
});
mqServer.RegisterHandler(m=>
{
//m.Body在这是一个什么东西
返回null;
});
mqServer.Start();
}
私有ServiceStack.Messaging.IMessage请求筛选器(ServiceStack.Messaging.IMessage消息)
{
if(message.Body是IProtocolContainer协议容器)
{
消息,正文=