如何使用 StackExchange.Redis 发布到 ServiceStack.Redis 消息队列?
How can I publish to a ServiceStack.Redis Message Queue using StackExchange.Redis?
我有现有的 ServiceStack 服务,我想一次切换到 StackExchange.Redis 一个。这涉及交换发送者和最终接收者。这个问题是关于从 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; }
}
}
这是我们的 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();
据我所知,Redis 键和值与我使用 ServiceStack 发布消息时生成的相同,但订阅者端发生了一些奇怪的事情。消息仅在服务首次启动时从队列中取出。之后放置在队列中的所有消息都保留在原处,直到服务重新启动。拾取的消息在反序列化对象上具有所有预期数据。
希望对 StackExchange.Redis 或 ServiceStack.Redis 有更多了解的人可以帮助解决这个问题。以防万一有人好奇:我们正在切换到 StackExchange.Redis 以便我们可以对 Redis 进行异步调用,ServiceStack.Redis 不支持。
如果您想知道客户端正在发送什么命令,您可以使用来自 redis-cli 的 Redis MONITOR debugging command,它可以让您实时查看向 redis 服务器发出的所有命令。
要模仿 Redis MQ 客户端,您还需要将队列的名称发布到 Redis Pub/Sub 主题 QueueNames.TopicIn
(mq:topic:in
) 以通知 Redis MQ Server消息已发布到该 MQ。
我有现有的 ServiceStack 服务,我想一次切换到 StackExchange.Redis 一个。这涉及交换发送者和最终接收者。这个问题是关于从 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; }
}
}
这是我们的 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();
据我所知,Redis 键和值与我使用 ServiceStack 发布消息时生成的相同,但订阅者端发生了一些奇怪的事情。消息仅在服务首次启动时从队列中取出。之后放置在队列中的所有消息都保留在原处,直到服务重新启动。拾取的消息在反序列化对象上具有所有预期数据。
希望对 StackExchange.Redis 或 ServiceStack.Redis 有更多了解的人可以帮助解决这个问题。以防万一有人好奇:我们正在切换到 StackExchange.Redis 以便我们可以对 Redis 进行异步调用,ServiceStack.Redis 不支持。
如果您想知道客户端正在发送什么命令,您可以使用来自 redis-cli 的 Redis MONITOR debugging command,它可以让您实时查看向 redis 服务器发出的所有命令。
要模仿 Redis MQ 客户端,您还需要将队列的名称发布到 Redis Pub/Sub 主题 QueueNames.TopicIn
(mq:topic:in
) 以通知 Redis MQ Server消息已发布到该 MQ。