config 配置
package com.app.common.redis.config;
import com.app.common.redis.enums.RedisPubSubTopicEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RedisSubConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public RedisMessageListenerContainer getRedisMessageListenerContainer(Executor executor) {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
applicationContext.getBeansOfType(RedisConnectionFactory.class).values().forEach(redisMessageListenerContainer::setConnectionFactory);
redisMessageListenerContainer.setTaskExecutor(executor);
for (MessageListener component : applicationContext.getBeansOfType(MessageListener.class).values()) {
List<PatternTopic> patternTopicList = Arrays.stream(RedisPubSubTopicEnum.values()).map(x -> new PatternTopic(x.name())).collect(Collectors.toList());
redisMessageListenerContainer.addMessageListener(new MessageListenerAdapter(component), patternTopicList);
}
return redisMessageListenerContainer;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
enums
package com.app.common.redis.enums;
public enum RedisPubSubTopicEnum {
CHAT_COMPLETIONS_PARAM_TOPIC,
CHAT_COMPLETIONS_RESULT_TOPIC,
;
}
receiver
抽象消息处理器
package com.app.common.redis.receiver;
import org.springframework.data.redis.connection.Message;
public abstract class RedisAbstractMsgProcessor {
public abstract String getTopicName();
public abstract void execute(Message message, byte[] bytes);
}
监听上下文管理器
package com.app.common.redis.receiver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
@Component
public class RedisReceiverContextListener implements MessageListener {
@Autowired
private ApplicationContext applicationContext;
private Map<String, RedisAbstractMsgProcessor> processorMap;
@Autowired
public void setProcessorMap() {
this.processorMap = applicationContext.getBeansOfType(RedisAbstractMsgProcessor.class).values().stream().collect(Collectors.toMap(RedisAbstractMsgProcessor::getTopicName, filterAlgorithm -> filterAlgorithm));
}
@Override
public void onMessage(Message message, byte[] bytes) {
RedisAbstractMsgProcessor processor = processorMap.get(new String(message.getChannel()));
if (Objects.isNull(processor)) {
log.info("找不到指定命令");
return;
}
processor.execute(message, bytes);
log.info("订阅消息,订阅名称:{},{}", new String(message.getChannel()), message);
}
}
Processor (分布式,微服务中的数据处理,每个微服务可能存在监听不一样的topic)
package com.app.service.module.ai.redis;
import com.alibaba.fastjson.JSON;
import com.app.common.gpt.dto.ChatCompletionResult;
import com.app.common.gpt.service.OpenAIAPIService;
import com.app.common.redis.enums.RedisPubSubTopicEnum;
import com.app.common.redis.receiver.RedisAbstractMsgProcessor;
import com.app.common.redis.util.RedisTools;
import com.app.service.bridge.dto.chat.ChatDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Slf4j
@Component
public class RedisChatParamProcessor extends RedisAbstractMsgProcessor {
@Autowired
private RedisTools redisTools;
@Autowired
private OpenAIAPIService openAIAPIService;
@Override
public String getTopicName() {
return RedisPubSubTopicEnum.CHAT_COMPLETIONS_PARAM_TOPIC.name();
}
@Override
public void execute(Message message, byte[] bytes) {
log.info("收到的redis chat 请求 订阅消息:{}", message.toString());
ChatDTO dto = JSON.parseObject(message.toString(), ChatDTO.class);
dto.setTargetType(2);
dto.setText("当前人数访问较多,请稍后再试~");
if (dto.getCheckStatus() == 3 && dto.getPlatform() == 1) {
dto.setText(dto.getSendMessage());
redisTools.sendMsg(RedisPubSubTopicEnum.CHAT_COMPLETIONS_RESULT_TOPIC, JSON.toJSONString(dto));
return;
}
log.info("【ChatRecordServiceImpl.executeBuildChatCompletion】- 聊天开始请求第三方GPT Chat 。 请求参数:{}", dto);
ChatCompletionResult completionResult = openAIAPIService.chatCompletions(dto.getAiKey(), dto.getUserId().toString(), dto.getSendMessage());
log.info("【ChatRecordServiceImpl.executeBuildChatCompletion】- 聊天结束完成请求返回结果:{}", completionResult);
if (Objects.nonNull(completionResult) && Objects.nonNull(completionResult.getChoices()) && !completionResult.getChoices().isEmpty()) {
dto.setText(completionResult.getChoices().get(0).getMessage().getContent());
redisTools.sendMsg(RedisPubSubTopicEnum.CHAT_COMPLETIONS_RESULT_TOPIC, JSON.toJSONString(dto));
return;
}
redisTools.sendMsg(RedisPubSubTopicEnum.CHAT_COMPLETIONS_RESULT_TOPIC, JSON.toJSONString(dto));
}
}
关注博主动态