第一步:创建一个发布者

package work;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; /**
* 发布
* author:songyan
* date: 2019/10/17
**/
public class Publisher extends Thread {
private final JedisPool jedisPool;
private String chanelName; public Publisher(JedisPool jedisPool, String chanelName) {
this.jedisPool = jedisPool;
this.chanelName = chanelName;
System.out.println("【发布者\""+chanelName+"\"初始化成功】");
System.out.println("请输入要发布的消息:");
} @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)) {
System.out.println(chanelName+"发布消息成功");
jedis.publish(chanelName, line);
} else {
break;
}
} catch (IOException e) {
e.printStackTrace();
} }
}
}

第二步:创建一个订阅者的监听器

package work;

import redis.clients.jedis.JedisPubSub;

/**
* 监听
* author:songyan
* date: 2019/10/17
**/
public class SubscriberListener extends JedisPubSub {
private String subName;
public SubscriberListener(String subName) {
this.subName = subName;
} // 取得订阅的消息后的处理
public void onMessage(String channel, String message) {
System.out.println(String.format("【"+subName + "接收到消息】频道:%s;消息:%s。" , channel , message));
} // 初始化订阅时候的处理
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println(String.format( "【"+subName + "订阅频道成功】频道:%s;频道数:%d。" , channel , subscribedChannels));
} // 取消订阅时候的处理
public void onUnsubscribe(String channelName, int subscribedChannels) {
System.out.println(String.format( "【"+subName + "取消订阅】频道:%s;频道数:%d。",channelName , subscribedChannels));
}
}

第三步:创建一个订阅者

package work;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; /**
* 订阅
* author:songyan
* date: 2019/10/17
**/
public class Subscriber extends Thread {
//jedis连接池
private final JedisPool jedisPool; private final SubscriberListener subscriberListener; private String channelName; public Subscriber(JedisPool jedisPool, SubscriberListener subscriberListener, String channelName) {
super();
this.jedisPool = jedisPool;
this.subscriberListener = subscriberListener;
this.channelName = channelName;
} @Override
public void run() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.subscribe(subscriberListener,channelName);// 通过jedis.subscribe()方法去订阅,入参是1.订阅者、2.频道名称
} catch (Exception e) {
e.printStackTrace();
System.out.println(String.format("频道订阅失败:%s",e));
} finally {
if (null != jedis)
jedis.close();
}
}
}

第四步:测试(编写客户端)

(1)发布者客户端

package work.test;

import redis.clients.jedis.JedisPool;
import work.Publisher; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* 发布测试
* author:songyan
* date: 2019/10/17
**/
public class PublishClient {
public static void main(String[] args) throws InterruptedException {
//创建连接池
JedisPool jedisPool = new JedisPool("192.168.159.133");
//创建线程池,并设定线程数量
ExecutorService executorService = Executors.newFixedThreadPool(5);
//创建一个发布者
Publisher publisher = new Publisher(jedisPool,"发布者1");
executorService.submit(publisher);
executorService.shutdown();
executorService.awaitTermination(600, TimeUnit.SECONDS);
}
}

执行main方法,创建一个发布者。

(2)订阅者客户端

package work.test;

import redis.clients.jedis.JedisPool;
import work.Subscriber;
import work.SubscriberListener; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* 订阅者客户端
* author:songyan
* date: 2019/10/17
**/
public class SubscriberClient { public static void main(String[] args) throws InterruptedException {
//创建redis连接池
JedisPool jedisPool = new JedisPool("192.168.159.133");
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(5); //创建订阅者
final SubscriberListener subscriberListener = new SubscriberListener("订阅者一号");
//订阅频道
Subscriber subscriber = new Subscriber(jedisPool, subscriberListener, "发布者1");
executorService.submit(subscriber);
executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.SECONDS); //30s后取消订阅
Thread.sleep(3000);
subscriberListener.onUnsubscribe("发布者1", 0);
}
}

执行main方法,创建一个订阅者(订阅上面发布者的频道)。

发布者发布信息:

订阅者接收到订阅信息:

订阅者取消订阅:

扩展:ExecutorService

Jedis实现频道的订阅,取消订阅的更多相关文章

  1. Redis的频道发布与消息订阅

    Redis的频道发布与消息订阅 官网介绍 进程间的一种通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 订阅/发布消息图 下图展示了频道channel1,以及订阅这个频道的三个客户端-c ...

  2. Firefox取消“订阅实时书签”功能

    如果你勾选了Firefox“总是用实时书签订阅收取”, 一打开RSS页面就直接弹出添订阅实时书签对话,而当你想在火狐中直接查看RSS页面时,发现不知如何取消“订阅实时书签”功能了.就怨这个关闭功能藏的 ...

  3. MQTT——取消订阅报文和断开连接报文

    笔者已经把连接报文,订阅报文,发布报文都讲解了完了.而接下来就是取消订阅报文和断开连接报文.和其他的报文比较的话,他们显示非常简单.甚至笔者觉得可以不必要拿出来讲.只要看一下MQTT文档就没有什么不清 ...

  4. RxJava2 中多种取消订阅 dispose 的方法梳理( 源码分析 )

    Github 相关代码: Github地址 一直感觉 RxJava2 的取消订阅有点混乱, 这样也能取消, 那样也能取消, 没能系统起来的感觉就像掉进了盘丝洞, 迷乱… 下面说说这几种情况 几种取消的 ...

  5. 如何取消 Google Cloud Platform 试用 & 关闭 GCP 帐号 & 删除信用卡 & 取消订阅

    如何取消 Google Cloud Platform 试用 & 关闭 GCP 帐号 & 删除信用卡 & 取消订阅 关闭您的 Google Cloud Platform 帐号 s ...

  6. ecshop邮件订阅按“订阅”没反应

    原订阅邮件所使用的JS文件transport.js和JQuery冲突,会更改transport.js文件,用以下代码可同样实现订阅功能. <input type="text" ...

  7. 使用SQLServer同义词和SQL邮件,解决发布订阅中订阅库丢失数据的问题

    最近给客户做了基于SQLServer的发布订阅的“读写分离”功能,但是某些表数据很大,经常发生某几条数据丢失的问题,导致订阅无法继续进行.但是每次发现问题重新做一次发布订阅又非常消耗时间,所以还得根据 ...

  8. Replication--使用备份初始化订阅--请求订阅

    1. 修改发布属性"许从备份文件初始化"置为TRUE 脚本修改:USE [DB01]GODECLARE @publication AS sysnameSET @publicatio ...

  9. Redis 订阅发布 - Jedis实现

    Redis 订阅发布 - Jedis实现 我想到使用Redis的订阅发布模式是用来解决推送问题的-. 对于概念性的叙述,多多少少还是要提一下的: ​ 什么是Redis发布订阅?Redis发布订阅是一种 ...

随机推荐

  1. Educational Codeforces Round 82 (Rated for Div. 2)D(模拟)

    从低位到高位枚举,当前位没有就去高位找到有的将其一步步拆分,当前位多余的合并到更高一位 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h&g ...

  2. python-excel读取-pyodbc

    https://github.com/mkleehammer/pyodbc/wiki/Cursor 利用pyodbc读取数据库,流程基本一样,就是配置connect对象时有所不同,下面是excel的: ...

  3. linux 下查看Tomcat的状态,以及开启停止服务命令

    1.首先进入你的tomcat 的bin目录下 cd /你的安装目录/tomcat/bin 查看服务启动情况 ps -ef|grep java 此条命令具体含义 ps:将某个进程显示出来 -A 显示所有 ...

  4. Centos610-oracle 备份和还原

    前言 本文是为基于Centos6.*(linux)系列的Oracle备份和还原的操作记录,其中根据expdp和impdp不同参数可实现不同场景下的导出导入,为不同OS下面的Oracle迁移打下基础. ...

  5. Dataset数据的XML持久化处理

    主要方法是用ADO.NET的DataTale 填充到Dataset Dataset 内置了XML持久化的方法,WriteXML和ReadXML:简单的WinFrom实例:从数据库的表 private ...

  6. Android输入法挤乱布局问题

    今天做布局的时候 嵌套的TbaleLayout里面有三行  但是准备输入的时候输入法自动将整个activity布局全部往上挤 导致输入框变小甚至消失  弄的很是郁闷 在网上查了之后  发现有些人是因为 ...

  7. Bugku-CTF之login3(SKCTF)(基于布尔的SQL盲注)

    Day41 login3(SKCTF)

  8. CTF_论剑场 头像

    首先打开链接发现这个链接是一个头像 然后下载这个头像 通过hxd分析一下 在编辑中查找 flag 然后发现flag是一个用base64 加密的一串文字 然后我们将这串文字 解密 然后再通过md5 32 ...

  9. sqli-libs(32-37(宽字节注入)关)

    补充知识:宽字节注入 定义:GB2312.GBK.GB18030.BIG5.Shift_JIS等这些都是常说的宽字节,实际上只有两字节.宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将 ...

  10. vue使用axios访问后台接口

    链接1:https://segmentfault.com/a/1190000012635783#item-2    // axios 使用post方式传递参数,后端接受不到,怎么解决 链接2:http ...