首先在Redis中尝试发布订阅
打开一个客户端监控char的渠道:
jjc@jjczn:/usr/local/webserver/redis-4.0.6/src$ ./redis-cli
127.0.0.1:6379> SUBSCRIBE char
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "char"
3) (integer) 1
再打开另一个客户端:
127.0.0.1:6379> publish char "ss"
(integer) 1
127.0.0.1:6379>
再看看监控char渠道的客户端:
127.0.0.1:6379> SUBSCRIBE char
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "char"
3) (integer) 1
1) "message"
2) "char"
3) "ss"
接收到了消息
在spring中配置发布订阅模式:
首先需要一个接受消息的类(发布订阅监听类),它实现MessageListener接口:
public class RedisMessageListener implements MessageListener {
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
private RedisTemplate redisTemplate;
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] body = message.getBody();//获取消息
String msgBody =(String) getRedisTemplate().getValueSerializer().deserialize(body);//使用值序列化器转换
System.out.println(msgBody);
byte[] channel = message.getChannel();//获取channel
String channelStr =(String) getRedisTemplate().getStringSerializer().deserialize(channel);//使用字符串序列化器转换
System.out.println(channelStr);
String bytesStr = new String(bytes);
System.out.println(bytesStr);//渠道名称转换
}
}
然后在spring中配置一个监听容器:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
">
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="50"></property>
<property name="maxTotal" value="100"></property>
<property name="maxWaitMillis" value="20000"></property>
</bean>
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"></property>
<property name="port" value="6379"></property>
<property name="poolConfig" ref="poolConfig"></property>
</bean>
<bean id="jdkSerializationRedisSerializer"
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="defaultSerializer" ref="stringRedisSerializer"></property>
<property name="keySerializer" ref="stringRedisSerializer"></property>
<property name="valueSerializer" ref="stringRedisSerializer"></property>
</bean>
<!--配置spring上下文监听类-->
<bean id="redisMsgListener" class="RedisMessageListener">
<property name="redisTemplate" ref="redisTemplate"></property>
</bean>
<bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer"
destroy-method="destroy">
<!--redis连接工厂-->
<property name="connectionFactory" ref="connectionFactory"></property>
<!--连接池-->
<property name="taskExecutor">
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="3"></property>
</bean>
</property>
<property name="messageListeners">
<map>
<!--监听者 key-ref和bean id要一致-->
<entry key-ref="redisMsgListener">
<!--监听类-->
<bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="chat"></constructor-arg>
</bean>
</entry>
</map>
</property>
</bean>
</beans>
这里配置了线程池,这个线程池将会持续的生存等待消息传入,这里配置了容器id为redisMsgListener的bean对渠道chat进行监听,当消息通过渠道chat发送的时候就会使用这个bean处理消息。
测试:convertAndSend方法是用来向渠道chat发送消息的。
@Test
public void xx() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
final RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);
String channel = "chat";
redisTemplate.convertAndSend(channel,"say hello");
}
输出:
say hello
chat
chat
注意如果是同一个消息,可能无法打印……比如第一次打印了 第二次无法打印 再隔4,5秒又可以打印了。时灵时不灵的……