spring使用redis作为消息订阅

redis可以用于消息订阅,下面一段代码实现了spring中使用redis作为消息订阅模型:

消息处理器:

Java 复制代码
/**
 * 接口RedisMessageHandler:
 */
public interface RedisMessageHandler {

    /**
     * 处理redis消息
     * @param message redis消息
     * @return 处理结果
     */
    String handlerRedisMessage(TMRedisMessage message);

}

实现消息处理:

java 复制代码
@Service
@Slf4j
public class ClusterMessageHandler implements RedisMessageHandler {

    @Override
    public String handlerRedisMessage(TMRedisMessage tmRedisMessage) {

        log.info("收到消息通知,消息内容:{}", tmRedisMessage);

        // 设置JWT信息
        JwtUtil.setJwtInfo(String.valueOf(tmRedisMessage.getAppId()), tmRedisMessage.getUin());

        // 构造集群组件创建/卸载请求
        var clusterRequest = new ClusterRequest();
        clusterRequest.setClusterId(tmRedisMessage.getClusterId());
        
        ClusterFactory.get(ClusterTypeEnum.COMMON.getName()).create(clusterRequest);

        JwtUtil.removeJwtInfo();

        return "success";
    }
}

消息消费者:

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencent.tbds.tm.platform.server.message.RedisMessageHandler;
import com.tencent.tbds.tm.platform.server.message.pojo.TMRedisMessage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
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 java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 类RedisConsumer:
 */

@Component
@Slf4j
public class RedisConsumer implements MessageListener {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private final Map<String, RedisMessageHandler> redisMessageHandlerMap;

    public RedisConsumer(ConfigurableApplicationContext context) {
        this.redisMessageHandlerMap = context.getBeansOfType(RedisMessageHandler.class);
    }

    @Override
    public void onMessage(Message message, byte[] bytes) {
        try {
            var channel = new String(message.getChannel());
            var body = new String(message.getBody());
            log.info("Received Redis message: {} from channel: {}", body, channel);
            var tmRedisMessage = new ObjectMapper().readValue(body, TMRedisMessage.class);
            var isSet = redisTemplate.opsForValue().setIfAbsent(tmRedisMessage.getClusterType() + tmRedisMessage.getEventsType(), "1", 5, TimeUnit.SECONDS);
            if (isSet != null && isSet) {
                for (var redisMessageHandler : redisMessageHandlerMap.values()) {
                    messageErrorHandler(redisMessageHandler, tmRedisMessage);
                }
            }

        } catch (Exception e) {
            log.error("Received Redis Message From Tm Error! ", e);
        }
    }

    /**
     * 消息处理错误处理
     * @param redisMessageHandler 请求处理类
     * @param tmRedisMessage 消息体
     */
    private void messageErrorHandler(RedisMessageHandler redisMessageHandler, TMRedisMessage tmRedisMessage) {
        var errMessage = "";
        try {
            var handlerClass = redisMessageHandler.getClass();
            var annotation = handlerClass.getAnnotation(MessageHandler.class);
            var clusterType = annotation.ClusterType();
            var eventsType = annotation.EventsType();
            if (clusterType.length == 0 && eventsType.length == 0) {
                log.info("{} Handler all Redis Message", handlerClass.getName());
                errMessage = redisMessageHandler.handlerRedisMessage(tmRedisMessage);
            } else {
                var clusterTypeList = Arrays.stream(clusterType)
                        .boxed()
                        .toList();
                var eventsTypes = Arrays.asList(eventsType);

                if (clusterTypeList.contains(tmRedisMessage.getClusterType()) &&
                        eventsTypes.contains(tmRedisMessage.getEventsType())) {
                    log.info("Invoke RedisMessageHandler to handler Message: {}", handlerClass.getName());
                    errMessage = redisMessageHandler.handlerRedisMessage(tmRedisMessage);
                }
            }
        } catch (Exception e) {
            errMessage = e.getMessage();
        }
        log.info("Redis message handler  result is {}", errMessage);
    }
}
相关推荐
宠友信息3 小时前
内容社区源码开发实践解析,用Spring Boot打造1:1仿小红书源码平台
java·spring boot·redis·websocket·mysql·spring·uni-app
hweiyu004 小时前
Redis命令:GET
redis
Su米苏4 小时前
Redis高级用法
spring boot·redis
AI人工智能+电脑小能手4 小时前
大白话说Java设计模式-34-命令模式(业务实战篇)
java·spring·设计模式·命令模式·异步任务·撤销重做·事务封装
殷紫川7 小时前
Spring 之父的 Agent 框架 Embabel:把"规划"从 LLM 手里抢回来
spring·ai编程
fatcoder8 小时前
玩转 Redis · Set 篇
前端·redis·后端
FfHUCisI8 小时前
Golang Redis 分布式锁
redis·分布式·golang
java1234_小锋8 小时前
Spring框架的创始人开发了一个Java AI智能体框架
java·人工智能·spring
程序猿乐锅8 小时前
从 dsh 源码看「一切皆插件」与 Spring IoC
java·网络·数据库·人工智能·后端·spring