package com.webgame.webgamebackend.common.utils; import com.alibaba.fastjson2.JSON; import io.micrometer.common.util.StringUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.stereotype.Component; import java.util.function.Consumer; /** * Redis消息队列工具类 * @author xzg */ @Slf4j @Component @RequiredArgsConstructor public class RedisMqUtil { private final RedisTemplate redisTemplate; private final RedisMessageListenerContainer redisMessageListenerContainer; public void pub(String channel, Object message) { try { if (StringUtils.isBlank(channel)) { log.warn("[REDIS消息队列] 发布信息失败: 通道名称为 null"); return; } if (message == null) { log.warn("[REDIS消息队列] 发布信息至通道({})失败: 信息体为 null", channel); return; } // 信息体转JSON var json = ""; try { json = JSON.toJSONString(message); } catch (Exception e) { log.warn("[REDIS消息队列] 发布信息至通道({})异常: 信息实体无法正确的序列化为JSON字符串, {}", channel, e.getMessage(), e); return; } redisTemplate.convertAndSend(channel, json); } catch (Exception e) { log.warn("[REDIS消息队列] 发布信息至通道({})异常: {}", channel, e.getMessage(), e); } } public void sub(String channel, Class clazz, Consumer callback) { if (StringUtils.isBlank(channel)) { log.warn("[REDIS消息队列] 订阅通道失败, 通道名称不可为空"); return; } if (callback == null) { log.warn("[REDIS消息队列] 订阅通道({})失败, 回调方法不可为空", channel); return; } try { var adapter = new MessageListenerAdapter((MessageListener) (message, pattern) -> { var body = message.getBody(); var channelName = new String(message.getChannel()); T dto; try { dto = JSON.parseObject(new String(body), clazz); } catch (Exception e) { log.error("[REDIS消息队列] 消费通道({})信息实体类型转换处理异常: {}, 信息: {}", channelName, e.getMessage(), body, e); return; } try { callback.accept(dto); } catch (Exception e) { log.error("[REDIS消息队列] 消费通道({})信息回调处理异常: {}, 信息: {}", channelName, e.getMessage(), body, e); } }); redisMessageListenerContainer.addMessageListener(adapter, new PatternTopic(channel)); } catch (Exception e) { log.error("[REDIS消息队列] 订阅通道({})异常: {}", channel, e.getMessage(), e); return; } log.info("[REDIS消息队列] 订阅通道({})成功", channel); } }