023_Jedis的发布和订阅

1. Redis为我们提供了publish/subscribe(发布/订阅)功能。我们可以对某个channel(频道)进行subscribe(订阅),当有人在这个channel上publish(发布)消息时, Redis就会通知我们, 这样我们可以收到别人发布的消息。

2. 作为Java的Redis客户端, Jedis提供了publish/subscribe的接口。本文讲述如何使用Jedis来实现Redis的publish/subscribe。

3. Jedis定义了抽象类JedisPubSub, 在这个类中, 定义publish/subsribe的回调方法。通过继承JedisPubSub类并重新实现这些回调方法, 当publish/subsribe事件发生时, 我们可以定制自己的处理逻辑。

4. 新建一个名为JedisPubSub的Java项目, 拷入相关jar包, 并添加到build path

5. 自定义发布和订阅的回调类

package com.redis.publish;

import redis.clients.jedis.JedisPubSub;

/**
 * 发布和订阅的回调类
 */
public class MyJedisPubSub extends JedisPubSub {
	private String clientName;
	
	public MyJedisPubSub(String clientName) {
		this.clientName = clientName;
	}
	
	@Override
	public void onMessage(String channel, String message) {
		System.out.println(String.format("%s客户端, 订阅%s频道, 接受到的消息是: %s", clientName, channel, message));
	}
	
	@Override
	public void onSubscribe(String channel, int subscribedChannels) {
		System.out.println(String.format("%s客户端, 订阅%s频道, 一共订阅%d个频道", clientName, channel, subscribedChannels));
	}
	
	@Override
	public void unsubscribe(String... channels) {
		super.unsubscribe(channels); // 这个一定要有, 不然取消订阅不生效
		
		for (String item : channels) {
			System.out.println(String.format("%s客户端, 取消订阅%s频道", clientName, item));
		}
	}
	
	@Override
	public void onUnsubscribe(String channel, int subscribedChannels) {
		System.out.println(String.format("%s客户端, 取消订阅%s频道, 还订阅%d个频道", clientName, channel, subscribedChannels));
	}
	
}

6. Jedis的subscribe操作

6.1. Jedis的subscribe的声明如下

public void subscribe(final JedisPubSub jedisPubSub, final String… channels)

6.2. 第一个参数接受一个JedisPubSub对象, 第二个参数指定对哪个频道进行订阅。上例中, 我们把我们自定义的MyJedisPubSub对象传给subscribe方法。当publish/subscribe的事件发生时, 会自动调用我们MyJedisPubSub的方法。

6.3. 由于Jedis的subscribe操作是阻塞的, 因此, 我们另起一个线程来进行subscribe操作。

7. 自定义订阅和取消订阅类

package com.redis.publish;

import redis.clients.jedis.Jedis;

/**
 * 订阅和取消订阅线程类
 */
public class SubscribeThread extends Thread {
	private Jedis jedis;
	private MyJedisPubSub myJedisPubSub;
	private String[] channels;
	
	public SubscribeThread(String clientName, String[] channels) {
		this.jedis = new Jedis("192.168.25.138", 6379);
		this.jedis.auth("lyw123456");
		this.myJedisPubSub = new MyJedisPubSub(clientName);
		this.channels = channels;
	}
	
	@Override
	public void run() {
		jedis.subscribe(myJedisPubSub, channels);
	}
	
	public void unsubscribe(String[] channels) {
		myJedisPubSub.unsubscribe(channels);
	}
	
}

8. 发布类

package com.redis.publish;

import redis.clients.jedis.Jedis;

/**
 * 发布类, 同时启动2个订阅客户端
 */
public class RedisPublish {
	public static void main(String[] args) {
		String cctv = "cctv";
		String ximalaya = "xi ma la ya";
		Jedis jedis = new Jedis("192.168.25.138", 6379);
		jedis.auth("lyw123456");
		
		SubscribeThread lisi = new SubscribeThread("lisi", new String[] {cctv});
		lisi.start();
		SubscribeThread zhangsan = new SubscribeThread("zhangsan", new String[] {cctv, ximalaya});
		zhangsan.start();
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		jedis.publish(cctv, "小冠快走");
		jedis.publish(ximalaya, "贞观长歌");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		zhangsan.unsubscribe(new String[] {cctv, ximalaya});
		jedis.publish(cctv, "新年快乐");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		lisi.unsubscribe(new String[] {cctv});
		jedis.close();
	}
}

9. 运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值