设为首页 收藏本站
查看: 994|回复: 0

[经验分享] Redis 订阅发布

[复制链接]

尚未签到

发表于 2017-12-21 06:18:41 | 显示全部楼层 |阅读模式
Redis 订阅发布 - Jedis实现
  我想到使用Redis的订阅发布模式是用来解决推送问题的~。
  对于概念性的叙述,多多少少还是要提一下的:
  ​ 什么是Redis发布订阅?Redis发布订阅是一种消息通信模式,发送者通过通道A发送消息message,订阅过通道A的客户端就可以接收到消息message。嗯度娘上面的解释要比我所说的好多了,而我所理解的就是:所谓的订阅发布模式,其实和我们看电视,听广播差不多,在我们没有调台(换频道)的时候,那个频道也是在传递消息的(发布)。我们换到那个频道上(订阅)就能接收到消息了。是的,虽然可能有些不恰当~
  说明
  ​ 本文中示例采用了三个客户端,以“品”字形排列,由上至下,由左至右分别为客户端1(c1),客户端2(c2),客户端3(c3).特此说明。

Redis订阅与发布命令
  首先声明,有关Redis服务器的搭建工作,请自行查阅相关资料进行环境抢建
  听说Redis中发布与订阅只有简单的6个命令。即:


  • PSUBSCRIBE pattern [pattern ...]
  • 订阅一个或者多个符合pattern格式的频道
  • PUBLISH channel message
  • 发布消息到chanel中
  • PUBSUB subcommand [argument [argument ...]]
  • 查看订阅与发布系统状态
  • PUNSUBSCRIBE [pattern [pattern ...]]
  • 退订所有符合格式的频道
  • SUBSCRIBE channel [channel ...]
  • 订阅一个或者多个频道
  • UNSUBSCRIBE [channel [channel ...]]
  • 取消订阅频道
例1 - SUBSCRIBE
  连接redis后键入命令
  ​ SUBSCRIBE study
DSC0000.png

  这样便订阅了一个名为study的频道。
  接下来study频道要发消息啦。~~

例2 - PUBLISH
  另开启一个客户端,我使用的是品字形布局的最上面那个做为发布者,键入
  ​ PUBLISH study "message1-go go go"
DSC0001.png

  可以看到,当客户端1在study频道发布消息时,客户端2(已订阅study频道)可以接收到c1发布的消息,而客户端3由于没有订阅study频道,所以接收不到c1发送的消息。

例3 - PSUBSCRIBE
  现在,跟着博主左手,右手一个慢动作。在c3中键入
  ​ PSUBSCRIBE study*
DSC0002.png

  OK,现在在c1中键入
  ​ PUBLISH study "message2"
  上结果图:
DSC0003.png

  c3采用的通配符的形式,也将study频道给订阅成功了。
  接下来,在c1中继续键入命令:
  ​ PUBLISH study:java "I hate java forever"
DSC0004.png

  可以看到,使用psubscribe不仅将study频道订阅了,而且将以study为首的频道也订阅了。

例4 - PUBSUB
  在c1中键入pubsub channel,可以获得:
  ​ 127.0.0.1:6379> PUBSUB channels
  
​ 1) "study"
  意为当前正在活跃的频道。

Jedis实现订阅发布者模式
  ​ 好了,上面通过命令行熟悉了一下Redis中有关订阅发布者模式的相关命令。下面我们要将redis的订阅与发布者嵌入到项目中。
  ​ 首先,我们使用jedis先订阅一个名为:study的频道
DSC0005.png

  然后我们先从命令行处进行消息发布:
DSC0006.png

  之后 ,我们使用jedis在项目中进行消息发布:
DSC0007.png

  我们可以进行正常的通信 ~噢耶~
  核心代码:

PublishMessage.java 用于开启一个发布消息的线程
  

private Logger logger = LoggerFactory.getLogger(PublishMessage.class);  

  
@Resource
  
private JedisCluster jedisCluster;
  

  
/**
  * 发布消息
  *
  * @param channel 频道
  * @param message 信息
  */
  
public void sendMessage(final String channel, final String message) {
  Thread thread = new Thread(() -> {
  Long publish = jedisCluster.publish(channel, message);
  logger.info("服务器在: {} 频道发布消息{} - {}", channel, message, publish);
  });
  logger.info("发布线程启动:");
  thread.setName("publishThread");
  thread.start();
  
}
  

ChatSubscribe.java用于处理订阅相关事件,继承自JedisPubSub
  

private Logger logger = LoggerFactory.getLogger(ChatSubscribe.class);  

  
// 取得订阅的消息后的处理
  
@Override
  
public void onMessage(String channel, String message) {
  logger.info("订阅成功,接收到的消息为:频道-{},消息-{}", channel, message);
  RedisString.message = message;
  
}
  

  
// 取得按表达式的方式订阅的消息后的处理
  
@Override
  
public void onPMessage(String pattern, String channel, String message) {
  System.out.println("-----取得按表达式的方式订阅的消息后的处理-----");
  System.out.println(pattern + "=" + channel + "=" + message);
  
}
  

  
// 初始化按表达式的方式订阅时候的处理
  
@Override
  
public void onPSubscribe(String pattern, int subscribedChannels) {
  System.out.println("-----初始化按表达式的方式订阅时候的处理-----");
  System.out.println(pattern + "=" + subscribedChannels);
  
}
  

  
// 取消按表达式的方式订阅时候的处理
  
@Override
  
public void onPUnsubscribe(String pattern, int subscribedChannels) {
  System.out.println("-----取消按表达式的方式订阅时候的处理-----");
  System.out.println(pattern + "=" + subscribedChannels);
  
}
  

  
@Override
  
public void onPong(String pattern) {
  super.onPong(pattern);
  
}
  

  
// 初始化订阅时候的处理
  
@Override
  
public void onSubscribe(String channel, int subscribedChannels) {
  logger.info("初始化订阅信息:频道-{},订阅频道-{}", channel, subscribedChannels);
  
}
  

  
// 取消订阅时候的处理
  
@Override
  
public void onUnsubscribe(String channel, int subscribedChannels) {
  logger.info("已取消订阅频道{}", channel);
  
}
  

SubScribeMessage.java 订阅频道,取消频道等动作类
  

private Logger logger = LoggerFactory.getLogger(SubScribeMessage.class);  

  
private ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  

  
@Resource
  
private JedisCluster jedisCluster;
  
/**
  * 订阅频道
  *
  * @param channel          频道
  * @param roomSubListerner
  */
  public void subscribeChannel(final String channel, final ChatSubscribe roomSubListerner) {
  

  cachedThreadPool.execute(new Runnable() {
  @Override
  public void run() {
  jedisCluster.subscribe(roomSubListerner, channel);
  }
  });
  }
  

  ​ jedisCluster是否封装工具类,取自各位看官,核心代码已给出,请各位看官根据自身业务与逻辑,自行更改与优化代码。
  ​ 本次示例程序采用tomcat 9.0 + spring + springmvc
  ​ 使用了诸如:@RestController,@GetMapping等相关注解,便于开发,有兴趣可自行查阅spring相关资料。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426278-1-1.html 上篇帖子: Redis 3.2.8 安装与配置 下篇帖子: redis-springboot
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表