2014-04-26 65 views
1

我有一個應用程序使用Redis發佈/訂閱在客戶端之間使用Java中的Jedis客戶端傳輸消息。我希望能夠在用戶輸入命令時在運行時訂閱頻道,但是因爲訂閱是阻止操作,因爲它在調用訂閱的線程上進行偵聽,所以我不確定如何在以後訂閱其他頻道在原始線程上。訂閱同一線程的多個頻道Jedis

例子:

private PubSubListener psl = new PubSubListener(); 

public void onCommand(String[] args) { 
    subscribe(args[0]); 
} 

public void subscribe(String channel) { 
    Jedis jedis = jedisPool.getResource(); 

    jedis.subscribe(psl, channel); 
} 

這只是分派則命令將被用於輪詢Redis的,我將無法訂閱任何更多的渠道與線程的線程工作。

回答

2

我觀察到同樣的問題,即訂閱線程一旦你訂閱就會阻塞。爲了解決這個問題,我使用Netty實現了優化的pub/sub客戶端,並將其合併到Jedis分支here中。這不是一個全面的解決方案,我還沒有來得及真正完成它,但它的工作原理基本渠道和模式subscriptions.The基礎是:

使用先拿發佈訂閱實例:

public static OptimizedPubSub getInstance(String host, int port, String auth, long timeout) 

問題/使用取消訂閱模式:

public ChannelFuture psubscribe(String... patterns) 
public ChannelFuture punsubscribe(String... patterns) 

可以忽略返回的ChannelFuture除非你想100%確定您的請求獲得通過(它的非同步)。

版本/使用取消訂閱的頻道:

public ChannelFuture subscribe(String... channels) 
public ChannelFuture unsubscribe(String... channels) 

然後實現SubListener實例:使用

public interface SubListener { 
    /** 
    * Callback when a message is published on a subscribed channel 
    * @param channel The channel the message was received on 
    * @param message The received message 
    */ 
    public void onChannelMessage(String channel, String message); 

    /** 
    * Callback when a message is published on a subscribed channel matching a subscribed pattern 
    * @param pattern The pattern that the channel matched 
    * @param channel The channel the message was received on 
    * @param message The received message 
    */ 
    public void onPatternMessage(String pattern, String channel, String message); 
} 

和註冊/註銷聽衆:

public void registerListener(SubListener listener) 
public void unregisterListener(SubListener listener) 

OptimizedPubSub從未塊和事件以異步方式傳遞到已註冊的子監聽器。

現在fork已經有點老了,所以它可能對你目前的形式沒有用處,但是你可以很容易地將源代碼放在那個包裏並且單獨構建它。依賴關係是Jedis和Netty。

對不起,我沒有一個更全面的解決方案。