redis从入门到精通(十)——— Redis消息发布和订阅

                                               Redis消息发布和订阅

 

Redis 通过 PUBLISH SUBSCRIBE 等命令实现了订阅与发布模式,

 

比如说,在下图展示的这个 pubsub_channels 示例中, client2 、 client5 和 client1 就订阅了 channel1 , 而其他频道也分别被别的客户端所订阅:

 

 

当客户端调用 SUBSCRIBE 命令时, 程序就将客户端和要订阅的频道在 pubsub_channels 字典中关联起来。

举个例子,如果客户端 client10086 执行命令 SUBSCRIBE channel1 channel2 channel3 ,那么前面展示的 pubsub_channels 将变成下面这个样子:

 

 

1.订阅频道

 

subscribe channel

 

例如:订阅my1

 

subscribe my1

 

 

 

2.批量订阅

 

psubscribe channel*

 

例如:psubscribe s*  批量订阅s开头的频道

 

3.在指定的频道中发布消息

 

publish channel content

1、publish key value

返回订阅者个数

 

 

主播(发布消息)

127.0.0.1:6379> publish news 'today is sunshine'

(integer) 0

 

订阅者1订阅主播

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "news"

3) (integer) 1

此时由于订阅再发布后,所有没有收到消息

 

主播(发布消息)

127.0.0.1:6379> publish news 'today is sunshine1'

(integer) 1

 

订阅者将得到消息

127.0.0.1:6379> subscribe news

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "news"

3) (integer) 1

1) "message"

2) "news"

3) "today is sunshine1"

 

 

Java篇

想使用jedis先引入依赖

<dependency>

    <groupId>redis.clients</groupId>

    <artifactId>jedis</artifactId>

    <version>2.9.0</version>

</dependency>

 

建立一个Publisher (发布者)

public class Publisher extends Thread{

 

    private final JedisPool jedisPool;

 

    public Publisher(JedisPool jedisPool) {

        this.jedisPool = jedisPool;

    }

   

    @Override

    public void run() {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        Jedis jedis = jedisPool.getResource();   //连接池中取出一个连接

        while (true) {

            String line = null;

            try {

                line = reader.readLine();

                if (!"quit".equals(line)) {

                    jedis.publish("mychannel", line);   //从 mychannel 的频道上推送消息

                } else {

                    break;

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

}

再建立一个订阅者

public class Subscriber extends JedisPubSub {

 

    public Subscriber(){}

    @Override

    public void onMessage(String channel, String message) {       //收到消息会调用

        System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));

    }

    @Override

    public void onSubscribe(String channel, int subscribedChannels) {    //订阅了频道会调用

        System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",

                channel, subscribedChannels));

    }

    @Override

    public void onUnsubscribe(String channel, int subscribedChannels) {   //取消订阅 会调用

        System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",

                channel, subscribedChannels));

 

    }

}

这里订阅者需要继承JedisPubSub,来重写它的三个方法。用途 注释上已经写了,很简单。

我们这里只是定义了一个订阅者,下面去订阅频道。

public class SubThread extends Thread {

 

    private final JedisPool jedisPool;

    private final Subscriber subscriber = new Subscriber();

 

    private final String channel = "mychannel";

 

    public SubThread(JedisPool jedisPool) {

        super("SubThread");

        this.jedisPool = jedisPool;

    }

 

    @Override

    public void run() {

        System.out.println(String.format("subscribe redis, channel %s, thread will be blocked", channel));

        Jedis jedis = null;

        try {

            jedis = jedisPool.getResource();   //取出一个连接

            jedis.subscribe(subscriber, channel);    //通过subscribe 的api去订阅,入参是订阅者和频道名

        } catch (Exception e) {

            System.out.println(String.format("subsrcibe channel error, %s", e));

        } finally {

            if (jedis != null) {

                jedis.close();

            }

        }

    }

}

最后,再写一个测试类去跑一下。键盘输入消息,订阅者就会触发onMessage方法

public class PubSubDemo {

 

    public static void main( String[] args )

    {

        // 连接redis服务端

        JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379);

       

        System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", "127.0.0.1", 6379));

 

        SubThread subThread = new SubThread(jedisPool);  //订阅者

        subThread.start();

 

        Publisher publisher = new Publisher(jedisPool);    //发布者

        publisher.start();

    }

}

看打印结果

https://images2018.cnblogs.com/blog/1098960/201803/1098960-20180301161138578-384562031.png

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值