Subscribe to multiple channels with same thread Jedis

最后都变了- 提交于 2019-12-12 21:02:56

问题


I have an application that uses Redis publish/subscribe to transfer messages between clients using the Jedis client in Java. I want to be able to subscribe to channels at runtime when the user types a command but as subscribe is a blocking operation as it listens on the thread that calls subscribe I'm not sure how to go about subscribing to other channels at a later date on the original thread.

Example:

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);
}

This would work except the thread that dispatches the command would then be used to poll Redis and I wouldn't be able to subscribe to any more channels with that thread.


回答1:


I observed the same problem, namely that the subscribing thread blocks once you subscribe. To address this, I implemented an optimized pub/sub client using Netty and incorporated it into a Jedis fork here. It's not a comprehensive solution and I have not had time to really finish it up, but it works for basic channel and pattern subscriptions.The basics are:

Acquire a pubsub instance using:

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

Issue/Cancel pattern subscriptions using:

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

you can ignore the returned ChannelFuture unless you want to make 100% certain your request gets through (it's asynch).

Issue/Cancel channel subscriptions using:

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

Then implement SubListener instances:

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);
}

and register/unregister the listeners using:

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

OptimizedPubSub never blocks and events are delivered to the registered SubListeners asynchronously.

The fork is a bit old now, so it may not be useful to you in its current form, but you can easily pull the source in that package and build it stand-alone. The dependencies are Jedis and Netty.

Sorry I did not have a more comprehensive solution.



来源:https://stackoverflow.com/questions/23310551/subscribe-to-multiple-channels-with-same-thread-jedis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!