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);
}
}