Jedis实现发布订阅功能
Redis为我们提供了publish/subscribe(发布/订阅)功能。我们可以对某个channel(频道)进行subscribe(订阅),当有人在这个channel上publish(发布)消息时,redis就会通知我们,这样我们可以收到别人发布的消息。
作为Java的redis客户端,Jedis提供了publish/subscribe的接口。本文讲述如何使用Jedis来实现redis的publish/subscribe。
定义Subscriber类
Jedis定义了抽象类JedisPubSub
,在这个类中,定义publish/subsribe的回调方法。通过继承JedisPubSub
类并重新实现这些回调方法,当publish/subsribe事件发生时,我们可以定制自己的处理逻辑。
在以下例子中,我们定义了Subscriber
类,这个类继承了JedisPubSub
类,并重新实现了其中的回调方法。
import redis.clients.jedis.JedisPubSub; public class Subscriber extends JedisPubSub {
public Subscriber() {
} public void onMessage(String channel, String message) {
System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));
} public void onSubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",
channel, subscribedChannels));
} public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",
channel, subscribedChannels)); }
}
定义SubThread线程类
由于Jedis的subscribe
操作是阻塞的,因此,我们另起一个线程来进行subscribe操作。
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; 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);
} catch (Exception e) {
System.out.println(String.format("subsrcibe channel error, %s", e));
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
在上面的代码中,我们从JedisPool
获取一个Jedis
实例,并使用这个Jedis
实例进行subscribe
的操作。Jedis
的subscribe
的声明如下:
public void subscribe(final JedisPubSub jedisPubSub, final String… channels)
第一个参数接受一个JedisPubSub
对象,第二个参数指定对哪个频道进行订阅。上例中,我们把我们定义的Subscriber
对象传给subscribe
方法。
当publish/subscribe的事件发生时,会自动调用我们Subscriber
的方法。
定义Publisher类
Publisher
类接受用户的输入,并将输入发布到channel。当用户输入”quit”后,输入结束。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; public class Publisher {
private final JedisPool jedisPool; public Publisher(JedisPool jedisPool) {
this.jedisPool = jedisPool;
} public void start() {
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);
} else {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
定义入口代码
如下是我们的程序入口代码。
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; public class PubSubDemo
{
public static void main( String[] args )
{
// 替换成你的reids地址和端口
String redisIp = "192.168.229.154";
int reidsPort = 6379;
JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), redisIp, reidsPort);
System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", redisIp, reidsPort)); SubThread subThread = new SubThread(jedisPool);
subThread.start(); Publisher publisher = new Publisher(jedisPool);
publisher.start();
}
}
在上面的代码中,我们首先生成了一个JedisPool
的redis连接池,这是由于Jedis
不是线程安全的,JedisPool
是线程安全的。而我们的程序在主线程和订阅线程(SubThread)均需要使用Jedis
,故在程序中我们使用JedisPool
。具体也可以参考在多线程环境中使用Jedis。
由于Jedis
的subcribe操作是阻塞的,故我们另起了一个线程来进行subcribe操作。
通过调用Publisher::start()
方法,接受用户的输入,并publish到指定的channel。
输出
redis pool is starting, redis ip 192.168.229.154, redis port 6379
subscribe redis, channel mychannel, thread will be blocked
subscribe redis channel success, channel mychannel, subscribedChannels 1
这时输入
hello
控制窗口中输出
receive redis published message, channel mychannel, message hello
参考资料
- https://github.com/xetorthio/jedis/wiki/AdvancedUsage
- http://basrikahveci.com/a-simple-jedis-publish-subscribe-example/
Jedis实现发布订阅功能的更多相关文章
- 如何使用jedis进行发布订阅
jedis实现发布订阅,是通过让发布者和订阅者同时对某个channel(频道)进行操作,订阅者订阅了某个频道例如channel1,发布者往这个channel1里面publish东西,在pubsubli ...
- 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能
springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...
- python开发-实现redis中的发布订阅功能
Python3学习(二十七):python实现Redis的订阅与发布(sub-pub机制) 先介绍一下redis的pub/sub功能: Pub/Sub功能(means Publish, Subscri ...
- Spring Boot 2.x基础教程:使用Redis的发布订阅功能
通过前面一篇集中式缓存的使用教程,我们已经了解了Redis的核心功能:作为K.V存储的高性能缓存. 接下来我们会分几篇来继续讲讲Redis的一些其他强大用法!如果你对此感兴趣,一定要关注收藏我哦! 发 ...
- SQL Server发布订阅功能研究
前提: 发布订阅只能是同一个内网的机器上才能使用,其实这个可以用配置管理器的别名功能设置之后就可以了,外网的也能通过这样的方式来搞. 配置过程参考老D的文章:http://www.cnblogs.co ...
- guava的事件发布订阅功能
事件的重要性,不用说很重要,在很多时候我们做完一个操作的时候,需要告知另外一个对象让他执行相应操作,比如当用户注册成功的时候,需要抛出一个注册成功的事件,那么有监听器捕获到这个事件,完成后续用户信息初 ...
- 关于SQL SERVER 2008 R2发布订阅功能
实现功能:主服务器维护数据的变更,从服务器需要时同步主服务器的数据. 配置:主从服务器均为SQL SERVER 2008 R2. 实现方法: 预备: 1.主从服务器需建立同一账户名及密码的账户(当时我 ...
- Redis 发布订阅,小功能大用处,真没那么废材!
今天小黑哥来跟大家介绍一下 Redis 发布/订阅功能. 也许有的小伙伴对这个功能比较陌生,不太清楚这个功能是干什么的,没关系小黑哥先来举个例子. 假设我们有这么一个业务场景,在网站下单支付以后,需要 ...
- Jedis的Publish/Subscribe功能的使用
redis内置了发布/订阅功能,可以作为消息机制使用.所以这里主要使用Jedis的Publish/Subscribe功能. 1.使用Spring来配置Jedis连接池 <!-- pool配置 - ...
随机推荐
- 企业架构研究总结(38)——TOGAF架构能力框架之架构能力建设和架构治理
为了确保架构功能在企业中能够被成功地运用,企业需要通过建立适当的组织结构.流程.角色.责任和技能来实现其自身的企业架构能力,而这也正是TOGAF的架构能力框架(Architecture Capabil ...
- AOP编程和ASP.NET MVC
AOP编程和ASP.NET MVC AOP(Aspect oriented programming)面向切面编程.说成切面不容易理解,代码哪里有切面?又不是三维物体.概念不管,我们从其思想来理解这个名 ...
- T-SQL查询语句(三):多表查询
SQL查询语句<三>:多表查询 (也叫连接查询,此处为基于两个表的连接查询)如果一个查询需要对多个表进行操作就称为连接查询,连接查询的结果集或结果称为表之间的连接.连接查询实际上是通过各个 ...
- webservice的调用方法
一.WebService在cs后台程序中的调用 A.通过命名空间和类名直接调用 示例: WebService ws = new WebService(); string s = ws.HelloWor ...
- 安装linux版qq,安装二进制包编译器,安装mysql-5.6.11,删除已安装或安装失败的mysql-5.6.11,简单mysql练习题
上午[root@localhost ~]# ./test3.sh dev1^C[root@localhost ~]# groupadd dev1[root@localhost ~]# vim /etc ...
- 纯Python综合图像处理小工具(3)10种滤镜算法
<背景> 滤镜处理是图像处理中一种非常常见的方法.比如photoshop中的滤镜效果,除了自带的滤镜,还扩展了很多第三方的滤镜效果插件,可以对图像做丰富多样的变换:很多手机app实现了实 ...
- C#开发 “因为某项目未能生成,所以无法发布”
今天把笔记本电脑中开发的项目复制到台式机上,启用调试都正常.准备发布的时候却提示“因为某项目未能生成,所以无法发布”的错误. 从网上查找资料可以通过以下方法解决: 在项目属性的签名标签中,创建测试证书 ...
- 内Cool超人
内Cool超人 经过一年时间看到asp.net mvc一直被受微软开发团队的注重.与之相比的silverlight我感觉到有点力不从心.除去silverlight第一次运行要安装Runtime不说,产 ...
- 自己做个 Tag标签
这是效果图,下面是源码,时间有限,有时间再完善 http://files.cnblogs.com/wxwall/tag.zip
- hdu 1809 求SG函数
A New Tetris Game(2) Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...