2013-06-24 41 views
2

我正在使用服务堆栈连接到Redis并使用SubPub功能。IRedis订阅连接

我应该保持IRedisSubscription和IRedisClient的实例化吗?例如,我应该将它分配给一个类级别的变量?

或者我可以简单地将其范围在using语句中,Service Stack将处理持久性?

也就是说,它的下面的例子是正确的:

公共类RedisPubSub1:IDisposable的{

private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString"); 
    private IRedisSubscription _subscription; 
    private IRedisClient _client; 

    private Action<string, string> _publish; 
    public event Action<string, string> Publish { 
     add { _publish += value; } 
     remove { _publish -= value; } 
    } 

    public RedisPubSub1() 
    {   
     Task.Factory.StartNew(() => 
      { 
       _client = ClientPool.GetClient(); 
       _subscription = _client.CreateSubscription(); 
        { 
         _subscription.OnMessage = EnqueEvent; 
         _subscription.SubscribeToChannels(new string[] { Channel }); 
        } 
     }); 
    } 

    private void EnqueEvent(string channel, string message) 
    { 
     if (_publish!= null) 
      _publish(channel, message); 
    }  

    public void Dispose() 
    { 
     _subscription.Dispose(); 
     _client.Dispose(); 


    } 
} } 

或者

公共类RedisPubSub2 {

private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString"); 

    private Action<string, string> _publish; 

    public event Action<string, string> Publish { 
     add { _publish += value; } 
     remove { _publish -= value; } 
    } 

    public RedisPubSub2() 
    {   
     Task.Factory.StartNew(() => 
      { 
       using(var _client = ClientPool.GetClient()) 
       { 
        using(_subscription = _client.CreateSubscription() 
        { 
         _subscription.OnMessage = EnqueEvent; 
         _subscription.SubscribeToChannels(new string[] { Channel }); 
        } 
       } 
     }); 
    } 

    private void EnqueEvent(string channel, string message) 
    { 
     if (_publish!= null) 
      _publish(channel, message); 
    }  } 

回答

2

的SubscribeToChannels阻止,因此,如果你保持一个参考连接或没有它不会出售,除非你最终的认购并不重要(即退订)。

您实现某种方式认购退订当你想,你不会想和线保持的积极认购,如RedisMqServer example看到,e.g做明智的做法:

using (var subscription = redisClient.CreateSubscription()) 
{ 
    subscription.OnUnSubscribe = channel => 
     Log.Debug("OnUnSubscribe: " + channel); 

    subscription.OnMessage = (channel, msg) => 
    { 
     if (msg == "STOP") 
     { 
      Log.Debug("UnSubscribe From All Channels..."); 
      subscription.UnSubscribeFromAllChannels(); //Un block thread. 
      return; 
     } 

     handleMessage(msg); 
    } 

    ... 

    //Unsubscribing will unblock this subscription: 
    subscription.SubscribeToChannels(QueueNames.TopicIn); //blocks thread 
} 
+0

谢谢!我想知道为什么这个电话被阻塞了,现在有道理。 – swestner

+0

嗨,我有一个问题,如果redis服务器重新启动会怎么样,它会阻止阻塞并继续前进?我们注意到,订阅在redis服务器重新启动后停止接收消息。我最初的计划是循环订阅,以便订户可以恢复丢失的连接。 – CodeLinguist

+1

@CodeLinguist该API映射接近Redis Pub/Sub命令,上面的示例不包括失败的redis服务器实例的任何自动重试逻辑。您可以使用[ServiceStack.Redis RedisPubSubServer](https://github.com/ServiceStack/ServiceStack.Redis#managed-pubsub-server)进行托管订阅,该托管订阅将在失败的连接上自动重新连接。 – mythz