首页 > 解决方案 > ServiceStack RedisMqServer:无法在运行时添加或删除通道?

问题描述

我现在已经“遗留”的使用 ServiceStack 实现发布/订阅解决方案的客户端很快就用完了,当它达到 20 个客户端限制时。

我们这样做:

_redisConsumer = MqClientFactory.Instance.GetRedisClient(); // Returns a IRedisClient
_subscription = _redisConsumer.CreateSubscription();
_subscription.OnSubscribe = channel => CoreLog.Instance.Info($"Subscription started on {eventChannelName}");
_subscription.OnUnSubscribe = channel => CoreLog.Instance.Warning($"Unsubscribed from {eventChannelName}");

_subscription.OnMessage = (channel, msg) =>
{
    try
    {
        onMessageReceived(CoreRequestJsonEnvelope.CreateCoreRequestFromJson(msg));
    }
    catch (Exception ex)
    {
        CoreLog.Instance.Exception(ex);
    }
};

// Since it blocks execution, we put this in a Task:
Task.Run(() => 
{
    try
    {
        _subscription.SubscribeToChannels(eventChannelName); // blocking
    }
    catch(Exception e) 
    { 
    }
});

当我们也有足够多的不同频道来收听时,它就用完了。

然后我想,也许不是为每个订阅都使用一个新的 IRedisClient,我可以为所有订阅使用相同的 IRedisClient,所以:

_redisConsumer = mySavedRedisClient;
...

Unknown reply on multi-request在几秒钟/执行后返回。

最后,我查看了RedisPubSubServer,但似乎我需要在构造函数中指定通道,之后我无法更改。我确实需要在运行时添加和删除通道,并且通道从一开始就不知道。

谢谢!

标签: redisservicestackpublish-subscribe

解决方案


目前尚不清楚您指的是什么 20 个客户端限制以及客户端限制如何依赖于频道或订阅者,但如果这是您的应用程序自己的限制,而不是听起来像增加这将是最简单的解决方案。

ServiceStack.Redis 不支持在订阅开始后更改订阅频道。IRedisSubscription您可能需要考虑使用ServiceStack.Redis Managed Pub/Sub Server ,而不是管理自己,它管理后台订阅线程,增加弹性并支持自动重试。

虽然您不能在运行时更改订阅的频道,但您可以修改修改Channels集合并重新启动订阅以创建对更新频道列表的新订阅,例如:

var pubSub = new RedisPubSubServer(clientsManager, chan1);
pubSub.Start();

//...

pubSub.Channels = new[] { chan1, chan2 };
pubSub.Restart();

否则,根据您的用例,您可能能够订阅频道模式,该模式允许您订阅匹配通配符频道模式的多个动态频道:

var pubSub = new RedisPubSubServer(clientsManager) {
       ChannelsMatching = new[] { "chan:*" }
    }
    .Start();

它将处理客户端发送的与通道模式匹配的任何消息。


推荐阅读