c# - ServiceStack.Redis.RedisClient 取消订阅函数挂起

标签 c# redis servicestack publish-subscribe

我尝试使用 RedisPubSubServer 但它不适用于关键通知,因为我需要订阅由模式指定的 channel 。所以我创建了自己的解决方案:

public class RedisKeySubscriber
{
    public string Host { get; private set; }
    public int Port { get; private set; }

    private readonly Dictionary<string, IRedisSubscription> _subscriptions;

    public RedisKeySubscriber(string host, int port)
    {
        Host = host;
        Port = port;
        _subscriptions = new Dictionary<string, IRedisSubscription>();
    }

    public void Subscribe(string key, Action<string, string> handler)
    {
        lock (_subscriptions)
        {
            IRedisSubscription subscription;
            if (_subscriptions.TryGetValue(key, out subscription))
                return;

            // FIXME this might potentially create too many threads
            var client = new ServiceStack.Redis.RedisClient(Host, Port);
            subscription = client.CreateSubscription();
            subscription.OnMessage = handler;
            _subscriptions.Add(key, subscription);
            new Thread(() => subscription.SubscribeToChannelsMatching(key)).Start();
        }
    }

    public void Unsubscribe(string key)
    {
        lock (_subscriptions)
        {
            IRedisSubscription subscription;
            if (!_subscriptions.TryGetValue(key, out subscription))
                return;
            subscription.UnSubscribeFromChannelsMatching(key);
            _subscriptions.Remove(key);
        }
    }

    public void UnsubscribeAll()
    {
        lock (_subscriptions)
        {
            foreach (var subscription in _subscriptions)
                subscription.Value.UnSubscribeFromChannelsMatching(subscription.Key);
            _subscriptions.Clear();
        }
    }

    public void Dispose()
    {
        UnsubscribeAll();
    }
}

我意识到这卡在 PSUBSCRIBE 命令上。其他一切都很好。有什么想法吗?

最佳答案

我使用额外的“控制” channel 解决了这个问题。因此,处理程序既订阅了与“key”匹配的 channel ,也订阅了像“CHCTRL:guid”这样的 channel ,其中 guid 是由类实例创建的特定 GUID。取消订阅函数在 CHCTRL:guid 上发布一条消息,处理程序可以理解是时候取消订阅了,因为消息不是来自“ key ”。

替代和建议的解决方案是不使用 ServiceStack.Redis。

关于c# - ServiceStack.Redis.RedisClient 取消订阅函数挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30037721/

相关文章:

c# - 使用 ServiceStack 服务的长池请求

c# - 如何计算给定索引周围 bool[,] 中的真实值?

c# - 需要解密 SAML 响应

Javascript (NodeJS) 回调范围

c# - 如何在 ServiceStack 中返回不同的 Http Status Code

servicestack - ServiceStack OrmLite如何检测对代码模型的更改并重新创建数据库?

c# - 自定义 OutputCache 提供程序不工作(调用 get 但未设置或添加)

c# - 文本字段字符串在 C# 中被删除

php - Laravel 5.5 Session 在每个请求中丢失

postgresql - 经常更新的最佳缓存策略数据(Redis/Memcached vs Nginx/Varnish vs Materialized view)