如果发布的redis是当前springboot配置的Redis,那就直接进行订阅!
导入maven
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
@Configuration
public class RedisSubscriber extends JedisPubSub{
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//订阅了一个叫chat 的通道
container.addMessageListener(new MessageListener(){
@Override
public void onMessage(Message message, byte[] pattern) {
String msg = new String(message.getBody());
System.out.println(new String(pattern) + "主题发布:" + msg);
//获取到通道消息进行解析msg,并处理
}
}, new PatternTopic("xxx")); //xxx:具体的通道名。如果是多个通道,那就直接复制setConnectionFactory就好
return container;
}
}
如果订阅的消息不是,当前配置的Redis,那就需要从新起一个线程,不然直接获取连接,会导致线程阻塞,因为redis本身是但线程的。
port org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;
@Configuration
public class RedisSubscriber extends JedisPubSub{
//在yaml里面的自定义的redis的链接进行获取
@Value("${video.host}") //ip
private String host;
@Value("${video.port}") //端口
private String port;
@Value("${video.password}") //密码
private String password;
@Bean
public void redisMessageListenerContainer() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(100);
jedisPoolConfig.setMaxWaitMillis(10000);
jedisPoolConfig.setMinIdle(8);
jedisPoolConfig.setMaxTotal(500);
jedisPoolConfig.setJmxEnabled(true);
jedisPoolConfig.setTestOnBorrow(true);
jedisPoolConfig.setTestOnReturn(true);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, Integer.valueOf(port), 100000, password);
SubThread subThread=new SubThread(jedisPool);
subThread.start();
}
}
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class SubThread extends Thread {
private final JedisPool jedisPool;
private final Subscriber subscriber = new Subscriber();
//订阅通道
private final String Channel1 = "Channel1";
private final String Channel2= "Channel2";
public SubThread(JedisPool jedisPool) {
super("SubThread");
this.jedisPool = jedisPool;
}
@Override
public void run() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource(); //取出一个连接
jedis.subscribe(subscriber, Channel1,Channel2) 【通道可配置单个或者多个,底层源码有体现】
} catch (Exception e) {
System.out.println(e);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPubSub;
@Component
public class Subscriber extends JedisPubSub {
// 这样写是因为 service无法注入的原因
public static XxxxService xxxxxService;
@Autowired
public void setSenderService(XxxxService xxxxxService){
Subscriber.XxxxService = xxxxxService;
}
public Subscriber(){}
@Override
public void onMessage(String channel, String message) { //收到消息会调用
//视频告警
//System.out.println("【"+channel + "】主题发布:" + message);
if("Channel1".equals(channel)){
//具体逻辑编写
}
}
}
或者:
Redis 消息发布订阅 与 Spring boot 使用快速入门_redis消息订阅与发布springboot-
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Redis 消息订阅-消息监听器,当收到阅订的消息时,会将消息交给这个类处理
* <p>
* 1、可以直接实现 MessageListener 接口,也可以继承它的实现类 MessageListenerAdapter.
* 2、自动多线程处理,打印日志即可看出,即使手动延迟,也不会影响后面消息的接收。
*
* @author wangMaoXiong
* @version 1.0
* @date 2022/5/21 16:00
*/
@Component
@Slf4j
public class RedisSubListener implements MessageListener {
// 直接从容器中获取
@Resource
private RedisTemplate redisTemplate;
/**
* 监听到的消息必须进行与发送时相同的方式进行反序列
* 1、订阅端与发布端 Redis 序列化的方式必须相同,否则会乱码。
*
* @param message :消息实体
* @param pattern :匹配模式
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// 消息订阅的匹配规则,如 new PatternTopic("basic-*") 中的 basic-*
String msgPattern = new String(pattern);
// 消息所属的通道,可以根据不同的通道做不同的业务逻辑
String channel = (String) redisTemplate.getStringSerializer().deserialize(message.getChannel());
// 接收的消息内容,可以根据自己需要强转为自己需要的对象,但最好先使用 instanceof 判断一下
Object body = redisTemplate.getValueSerializer().deserialize(message.getBody());
// 收到 Redis 订阅消息: channel=basic-service body=flushDb pattern=basic-*
// 收到 Redis 订阅消息: channel=memoryCache body=flushAll pattern=memoryCache
log.info("收到 Redis 订阅消息: channel={} body={} pattern={} ", channel, body, msgPattern);
// 手动延迟,模拟数据处理
log.info("------------数据处理完成.......");
}
}
package com.spiceIngredients.web.monitoring.redis;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;
import javax.annotation.Resource;
@Configuration
public class RedisSubscriber{
@Resource
private RedisSubListener redisSubListener;
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
// 设置连接工厂,RedisConnectionFactory 可以直接从容器中取,也可以从 RedisTemplate 中取
container.setConnectionFactory(connectionFactory);
// 订阅名称叫 memoryCache 的通道, 类似 Redis 中的 subscribe 命令
container.addMessageListener(redisSubListener, new ChannelTopic("memoryCache"));
// 订阅名称以 'basic-' 开头的全部通道, 类似 Redis 的 pSubscribe 命令
container.addMessageListener(redisSubListener, new PatternTopic("basic-*"));
return container;
}
}