C# 如何使用StackExchange.Redis发布到ServiceStack.Redis消息队列?
我有要切换到StackExchange.Redis的现有ServiceStack服务,一次一个。这涉及到交换发送方和最终接收方。这个问题是关于从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
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,这样您就可以准确地看到正在发送的命令,这简直就是一个简单的命令。我会试一试。我想正是我使用的工具给我带来了麻烦。监视器没有向控制台写入任何内容。