我尝试使用RedisPubSubServer,但这不适用于按键通知,因为我需要订阅由模式指定的通道。因此,我创建了自己的解决方案:
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命令上挂起。其他一切都运行得很好。有什么想法吗?
发布于 2015-05-05 17:20:01
我用一个额外的“控制”通道解决了这个问题。因此,处理程序既订阅了与'key‘匹配的通道,也订阅了类似'CHCTRL: guid’的通道,其中GUID是由类实例创建的特定GUID。取消订阅函数在CHCTRL:guid上发布一条消息,处理程序可以理解是时候取消订阅了,因为该消息不是来自“key”。
另一种建议的解决方案是不使用ServiceStack.Redis。
https://stackoverflow.com/questions/30037721
复制相似问题