欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

redis订阅发布示例,redis订阅示例,下面的代码使用redis

来源: javaer 分享于  点击 4956 次 点评:51

redis订阅发布示例,redis订阅示例,下面的代码使用redis


下面的代码使用redis实现订阅/发布。需要jedis的2.0.0和SLF4J的jar包。

在redis中可以同时订阅多个频道,如果有消息发布是redis会发出通知。jedis中提供了JedisPubSub抽象类来提供发布/订阅的机制,在实际应用中需要实现JedisPubSub类。

package cn.outofmemory.redis;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.JedisPubSub;public class Subscriber extends JedisPubSub {    private static Logger logger = LoggerFactory.getLogger(Subscriber.class);    @Override    public void onMessage(String channel, String message) {        logger.info("Message received. Channel: {}, Msg: {}", channel, message);    }    @Override    public void onPMessage(String pattern, String channel, String message) {    }    @Override    public void onSubscribe(String channel, int subscribedChannels) {    }    @Override    public void onUnsubscribe(String channel, int subscribedChannels) {    }    @Override    public void onPUnsubscribe(String pattern, int subscribedChannels) {    }    @Override    public void onPSubscribe(String pattern, int subscribedChannels) {    }}

上面的类是从JedisPubSub继承的类,我要用它来订阅一些频道,并获得消息。

main方法如下

package cn.outofmemory.redis;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class Program {    public static final String CHANNEL_NAME = "commonChannel";    private static Logger logger = LoggerFactory.getLogger(Program.class);    public static void main(String[] args) throws Exception {        JedisPoolConfig poolConfig = new JedisPoolConfig();        JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379, 0);        final Jedis subscriberJedis = jedisPool.getResource();        final Subscriber subscriber = new Subscriber();        new Thread(new Runnable() {            @Override            public void run() {                try {                    logger.info("Subscribing to \"commonChannel\". This thread will be blocked.");                    subscriberJedis.subscribe(subscriber, CHANNEL_NAME);                    logger.info("Subscription ended.");                } catch (Exception e) {                    logger.error("Subscribing failed.", e);                }            }        }).start();        Jedis publisherJedis = jedisPool.getResource();        new Publisher(publisherJedis, CHANNEL_NAME).start();        subscriber.unsubscribe();        jedisPool.returnResource(subscriberJedis);        jedisPool.returnResource(publisherJedis);    }}

在上面的例子中,我们使用JedisPool来获得Jedis的实例。 Jedis类是非线程安全的,但是JedisPool是线程安全的。我使用了两个Jedis实例,一个用来发布消息,另一个订阅频道。

我在另外一个线程中实现订阅。

下面的类实现发布消息到redis的频道中。

package cn.outofmemory.redis;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.Jedis;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Publisher {    private static final Logger logger = LoggerFactory.getLogger(Publisher.class);    private final Jedis publisherJedis;    private final String channel;    public Publisher(Jedis publisherJedis, String channel) {        this.publisherJedis = publisherJedis;        this.channel = channel;    }    public void start() {        logger.info("Type your message (quit for terminate)");        try {            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));            while (true) {                String line = reader.readLine();                if (!"quit".equals(line)) {                    publisherJedis.publish(channel, line);                } else {                    break;                }            }        } catch (IOException e) {            logger.error("IO failure while reading input, e");        }    }}

上面的类获得用户的控制台输入,然后发布到redis channel,当用户键入quit时则退出循环

关键点如下:

要在单独的线程中订阅, 因为subscribe会阻塞当前线程的执行。 你可以使用一个PubSub实例来订阅多个Channel注意Jedis实例是非线程安全的当需要创建多个jedis实例时要使用JedisPool类,当使用完jedis对象时要放回JedisPool。
相关栏目:

用户点评