servicestack.redis,C#,Redis,Stackexchange.redis,servicestack.redis" /> servicestack.redis,C#,Redis,Stackexchange.redis,servicestack.redis" />

C# 如何使用StackExchange.Redis发布到ServiceStack.Redis消息队列?

C# 如何使用StackExchange.Redis发布到ServiceStack.Redis消息队列?,c#,redis,stackexchange.redis,servicestack.redis,C#,Redis,Stackexchange.redis,servicestack.redis,我有要切换到StackExchange.Redis的现有ServiceStack服务,一次一个。这涉及到交换发送方和最终接收方。这个问题是关于从StackExchange.Redis发布到ServiceStack.Redis的 这是一个简单的发布者,我把它放在一个控制台应用程序中测试这个概念 namespace SEMQSender { public class MessagePublisher { IConnectionMultiplexer _connecti

我有要切换到StackExchange.Redis的现有ServiceStack服务,一次一个。这涉及到交换发送方和最终接收方。这个问题是关于从StackExchange.Redis发布到ServiceStack.Redis的

这是一个简单的发布者,我把它放在一个控制台应用程序中测试这个概念

namespace SEMQSender
{
    public class MessagePublisher
    {
        IConnectionMultiplexer _connectionMultiplexer;
        public MessagePublisher()
        {
            _connectionMultiplexer = ConnectionMultiplexer.Connect(new ConfigurationOptions()
            {
                EndPoints = {
                        {
                        "MyRedisServer"
                        }
                },
                DefaultDatabase = 0,
                AllowAdmin = true,
                SyncTimeout = 100000
            });
        }

        public void Run()
        {
            var request = new MyRequest()
            {
                Id = 27
            };
            PushServiceStackRequest(request);
        }

        public void PushServiceStackRequest<T>(T request)
        {
            var messageText = SerializeRequestAsServiceStackMessage(request);
            Push($"mq:{request.GetType().Name}.inq", messageText);
        }

        public string SerializeRequestAsServiceStackMessage<T>(T request)
        {
            var requestJson = JsonSerializer.Serialize(request);
            requestJson.Remove(0, 1);
            var serviceStackMessage = new ServiceStackMessage()
            {
                Id = Guid.NewGuid(),
                CreatedDate = DateTimeOffset.Now,
                Options = 1,
                Priority = 0,
                RetryAttempts = 0
            };
            var messageJson = JsonSerializer.Serialize(serviceStackMessage);
            var requestType = request.GetType();
            var sBuilder = new StringBuilder();
            sBuilder.AppendJoin('.', requestType.Namespace.Split('.').Take(2));
            var ns = sBuilder.ToString();
            var result = $"{messageJson.Remove(messageJson.Length - 1, 1)}, \"Body\":{{\"__type\":\"{requestType.FullName}, {ns}\",{requestJson.Remove(0, 1)}}}";
            return result;
        }

        public void Push(RedisKey queueName, RedisValue value)
        {
            _connectionMultiplexer.GetDatabase().ListRightPush(queueName, value);
        }
    }

    public class ServiceStackRedisMessage
    {
        public Guid Id { get; set; }
        public DateTimeOffset CreatedDate { get; set; }
        public int Priority { get; set; }
        public int RetryAttempts { get; set; }
        public int Options { get; set; }
    }
}

namespace MyServiceStackService.ServiceModel.MyService
{
    public class MyRequest
    {
        public int Id { get; set; }
    }
}
名称空间SEMQSender
{
公共类消息发布者
{
i连接多路复用器_连接多路复用器;
公共消息发布者()
{
_connectionMultiplexer=connectionMultiplexer.Connect(新配置选项()
{
端点={
{
“MyRedisServer”
}
},
DefaultDatabase=0,
AllowAdmin=true,
同步超时=100000
});
}
公开募捐
{
var request=new MyRequest()
{
Id=27
};
PushServiceStackRequest(请求);
}
公共无效PushServiceStackRequest(T请求)
{
var messageText=SerializeRequestAsServiceStackMessage(请求);
Push($“mq:{request.GetType().Name}.inq”,messageText);
}
公共字符串序列化RequestAsserviceStackMessage(T请求)
{
var requestJson=JsonSerializer.Serialize(请求);
Remove(0,1);
var serviceStackMessage=新serviceStackMessage()
{
Id=Guid.NewGuid(),
CreatedDate=DateTimeOffset。现在,
选项=1,
优先级=0,
重试次数=0
};
var messageJson=JsonSerializer.Serialize(serviceStackMessage);
var requestType=request.GetType();
var sBuilder=新的StringBuilder();
sBuilder.AppendJoin('.',requestType.Namespace.Split('.').Take(2));
var ns=sBuilder.ToString();
var result=$“{messageJson.Remove(messageJson.Length-1,1)},\“Body\”:{{{\“\uuu type\”:\“{requestType.FullName},{ns}\”,{requestJson.Remove(0,1)}”;
返回结果;
}
公共无效推送(RedisKey queueName、RedisValue)
{
_connectionMultiplexer.GetDatabase().ListRightPush(队列名称,值);
}
}
公共类ServiceStackMessage
{
公共Guid Id{get;set;}
公共日期时间偏移量CreatedDate{get;set;}
公共int优先级{get;set;}
公共整数重试次数{get;set;}
公共int选项{get;set;}
}
}
命名空间MyServiceStackService.ServiceModel.MyService
{
公共类MyRequest
{
公共int Id{get;set;}
}
}
这是我们的ServiceStack服务如何订阅redis消息的一个示例

    container.Register<IRedisClientsManager>(c => new RedisManagerPool(ConfigurationManager.AppSettings["Redis"]));
    container.Register<ICacheClient>(c => container.Resolve<IRedisClientsManager>().GetCacheClient());
    var mqHost = new RedisMqServer(container.Resolve<IRedisClientsManager>(), retryCount: 2);
    container.Register<IMessageService>(c => mqHost);

    mqHost.RegisterHandler<MyRequest>(this.ServiceController.ExecuteMessage);

    mqHost.Start();
container.Register(c=>newredismanagerpool(ConfigurationManager.AppSettings[“Redis”]);
Register(c=>container.Resolve().GetCacheClient());
var mqHost=new RedisMqServer(container.Resolve(),retryCount:2);
Register(c=>mqHost);
mqHost.RegisterHandler(this.ServiceController.ExecuteMessage);
mqHost.Start();
据我所知,Redis键和值与使用ServiceStack发布消息时生成的相同,但在订户端发生了一些奇怪的事情。只有在服务首次启动时,才会从队列中拾取消息。在此之后放置在队列上的所有消息都保留在原来的位置,直到服务重新启动。拾取的消息具有反序列化对象上的所有预期数据


希望对StackExchange.Redis或ServiceStack.Redis有更多了解的人能帮上忙。以防有人好奇:我们正在切换到StackExchange.Redis,这样我们就可以对Redis进行异步调用,而ServiceStack.Redis不支持这种调用。

如果您想知道客户端正在发送什么命令,可以使用Redis cli中的Redis,它可以让您实时查看发送到Redis服务器的所有命令


要模拟Redis MQ客户端,您还需要将队列的名称发布到Redis发布/子主题
QueueNames.TopicIn
MQ:Topic:in
),该主题通知消息已发布到该MQ。

这是否是QueueNames.TopicIn的键,作为一个列表,其中一个值为MyRequest:in?我无法让显示器在我的机器上工作。是一个静态字符串,其值为“mq:topic:in”,这更有意义,感谢链接。这会让我认为将mq:MyRequest.inq的值发布到mq:topic:in应该有效吗?到目前为止,我已经尝试了mq:MyRequest.inq、mq:MyRequest、MyRequest.inq和MyRequest。他们现在都在名单上,实际的请求也是如此itself@Sorrien将消息发布到是暂时的,即它不会持久存在于列表中。我建议您运行MONITOR,这样您就可以准确地看到正在发送的命令,这简直就是一个简单的命令。我会试一试。我想正是我使用的工具给我带来了麻烦。监视器没有向控制台写入任何内容。