API
-
publish
发布命令,
publish channel message
PUBLISH sohu "hello world!"
返回值是订阅者的数量。
-
subscribe
订阅命令
SUBSCRIBE sohu
此时处于监听状态,一旦有新的消息发布,可以收到并展示。
-
unsubscribe
取消订阅,其实在退出当前客户端时就自动取消订阅了。
UNSUBSCRIBE [channel [channel ...]]
退订一个或多个频道,如果执行时没有给定任何频道,那么退订所有频道。
-
psubscribe
订阅与给定模式相匹配的所有频道
#PSUBSCRIBE pattern [pattern ...] PSUBSCRIBE s*
-
punsubscribe
退订指定的模式
#PUNSUBSCRIBE pattern [pattern ...] PUNSUBSCRIBE s*
-
PUBSUB
# 列出至少有一个订阅者的频道 PUBSUB CHANNELS # NUMSUB [channel-1 .. channel-N] # 列出给定频道(sohu)的订阅者数量 PUBSUB NUMSUB sohu # 列出所有通过模式匹配方式的订阅者数量,没有参数 PUBSUB NUMPAT
注意,模式匹配和指定频道的匹配是分开统计的,虽然
PSUBSCRIBE s*
也能订阅到sohu
,但是PUBSUB NUMSUB sohu
并不能统计到。同样的,PUBSUB NUMPAT
不能统计SUBSCRIBE sohu
的数量。
Jedis演示
public class RedisSub extends JedisPubSub {
public static void main(String[] args) throws InterruptedException {
RedisSub redisSub = new RedisSub();
JedisPool jedisPool = new JedisPool();
Runnable runnable = () -> jedisPool.getResource().subscribe(redisSub, "programmer");
new Thread(runnable).start();
TimeUnit.SECONDS.sleep(1);
jedisPool.getResource().publish("programmer", "a");
TimeUnit.SECONDS.sleep(1);
jedisPool.getResource().publish("programmer", "b");
TimeUnit.SECONDS.sleep(4);
redisSub.unsubscribe("programmer");
}
@Override
public void onMessage(String channel, String message) {
System.out.println("收到来自" + channel + "频道的消息" + message);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println("退订来自" + channel + "频道的消息");
}
}
输出如下:
收到来自programmer频道的消息a
收到来自programmer频道的消息b
退订来自programmer频道的消息
Springboot集成
参考spring boot集成redis的基本配置配置Gradle依赖及连接池.
发布
直接使用RedisTemplate::convertAndSend
发布.
订阅
在Springboot
中使用发布订阅模式比较简单,只需要继承MessageListenerAdapter
,通过RedisMessageListenerContainer
绑定指定的一个或多个Topic
(ChannelTopic
或者PatternTopic
)后,重写onMessage
方法来自定义业务操作.最终将组件注入到容器中即可发挥作用.非常容易扩展.
这里以自定义的总监听(RedisCommonMsgListener
)和登录监听(RedisUserMsgListener
)为例.
RedisCommonMsgListener:
@Slf4j
@Component
public class RedisCommonMsgListener extends MessageListenerAdapter {
@Autowired
public RedisCommonMsgListener(RedisMessageListenerContainer messageListenerContainer) {
messageListenerContainer.addMessageListener(this, new PatternTopic("*"));
}
@Override
public void onMessage(Message message, byte[] pattern) {
log.info("接收到Redis的消息:{}", new String(message.getBody()));
}
}
RedisUserMsgListener:
@Slf4j
@Component
public class RedisUserMsgListener extends MessageListenerAdapter {
@Autowired
public RedisUserMsgListener(RedisMessageListenerContainer messageListenerContainer) {
LinkedList<Topic> topics = new LinkedList<Topic>() {{
add(new ChannelTopic("swb:user:login"));
add(new ChannelTopic("swb:user:logout"));
}};
messageListenerContainer.addMessageListener(this, topics);
}
@Override
public void onMessage(Message message, byte[] pattern) {
String name = new String(message.getBody());
String topic = new String(pattern);
String option = null;
if ("swb:user:login".equals(topic)) {
option = "登录";
}
if ("swb:user:logout".equals(topic)) {
option = "退出";
}
log.info("user[{}]{}了系统.", name, option);
}
}