redis提供了一种发布订阅机制,在redis命令行中可以使用SUBSCRIBE命令进行订阅,使用PUBLISH命令进行发布。订阅方可以收到发布方发过来的消息。发布者并不知道他有多少人订阅,可以看作往一个channel推送消息。而订阅者也不知道发布者是谁,只是从channel中读取订阅的消息。订阅者可以订阅多个channel。
redis命令行下订阅first和second两个channel
127.0.0.1:6379> SUBSCRIBE first second
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "first"
3) (integer) 1
1) "subscribe"
2) "second"
3) (integer) 2
订阅后发回的消息有三条
- “subscribe”:消息类型,返回subscribe表示订阅成功。
- “first”:channel名称。
- (integer) 1:当前活跃channel数量。
redis命令行下向first发布消息
127.0.0.1:6379> PUBLISH first "Hello first"
(integer) 1
订阅者受到的消息
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "first"
3) (integer) 1
1) "subscribe"
2) "second"
3) (integer) 2
1) "message"
2) "first"
3) "Hello first"
在java中使用
消息监听类
@Component
public class TestSub implements MessageListener {
public TestSub(){
System.out.println("TestSub init");
}
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] body = message.getBody();//请使用valueSerializer
byte[] channel = message.getChannel();
String msg = (String)stringRedisTemplate.getDefaultSerializer().deserialize(body);
String topic = (String)stringRedisTemplate.getDefaultSerializer().deserialize(channel);
System.out.println("我是sub2,监听"+topic+",我收到消息:"+msg);
}
}
配置监听器
@Configuration
public class RedisConfig {
//初始化监听器
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new PatternTopic("second"));//second是channel名称
return container;
}
//利用反射来创建监听到消息之后的执行方法
@Bean
MessageListenerAdapter listenerAdapter(MessageReceiver messageReceiver) {
return new MessageListenerAdapter(messageReceiver, "receiveMessage");
}
//使用默认的工厂初始化redis操作模板
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
推送消息
stringRedisTemplate.convertAndSend("second","java number 1");