基于Redis发布订阅模式案例

1、 背景

用户发送消息给某个人,后台服务器保存用户信息记录,并短信通知该用户或者单独记录日志到日志系统
1、用户发送记录保存
2、记录发送记录的日志/或者发送短信给该用户

2、 redis发布订阅模式配置
@Configuration
public class RedisPubSubConfig {

    @Autowired
    private RedisTemplate redisTemplate;

    @Bean
    RedisMessageListenerContainer redisContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisTemplate.getConnectionFactory());
        //需要多个方法监听可以加入多个订阅者
        container.addMessageListener(messageListenerAdapter() , topic());
        container.addMessageListener(messageLogListenerAdapter(), topic());
        //序列化对象
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        container.setTopicSerializer(seria);
        return container;
    }

    @Bean
    MessageListenerAdapter messageListenerAdapter() {
        return new MessageListenerAdapter(redisMessageSubscriber());
    }
    @Bean
    MessageListenerAdapter messageLogListenerAdapter() {
        return new MessageListenerAdapter(redisMessageLogSubscriber());
    }
    @Bean
    public RedisMessageSubscriber redisMessageSubscriber() {
        return new RedisMessageSubscriber();
    }
    @Bean
    public RedisMessageLogSubscriber redisMessageLogSubscriber() {
        return new RedisMessageLogSubscriber();
    }
    @Bean
    ChannelTopic topic() {
        return new ChannelTopic("chatChannel");
    }
    @Bean
    MessagePublisher redisPublisher() {
        return new RedisMessagePublisher(redisTemplate, topic());
    }
}

3、 保存记录订阅者和记录日志订阅者
@Slf4j
public class RedisMessageLogSubscriber implements MessageListener {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        RedisSerializer serializer = redisTemplate.getValueSerializer();
        SendMsgParam sendMsgParam = (SendMsgParam) serializer.deserialize(message.getBody());
        log.info("im-server chat info message:{}", sendMsgParam);
    }
}
@Slf4j
public class RedisMessageSubscriber implements MessageListener {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    ImUserChatRecordService       imUserChatRecordService;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        RedisSerializer serializer = redisTemplate.getValueSerializer();
        SendMsgParam sendMsgParam = (SendMsgParam) serializer.deserialize(message.getBody());
        imUserChatRecordService.saveChatMsg(sendMsgParam);
    }
}
4、 发布者
@Setter
public class RedisMessagePublisher implements MessagePublisher {

    private RedisTemplate redisTemplate;

    private ChannelTopic topic;

    private RedisMessagePublisher() { }

    public RedisMessagePublisher(RedisTemplate redisTemplate, ChannelTopic topic) {
        this.redisTemplate = redisTemplate;
        this.topic = topic;
    }

    @Override
    public void publish(SendMsgParam message) {
        redisTemplate.convertAndSend(topic.getTopic(), message);
    }
}
5、 消息发送者
@Controller
public class ImWsController {


    @Autowired
    private MessagePublisher redisPublisher;

    /**
    *   发送
    * @since 2020/1/7
    */
    @MessageMapping("/send/{type}/{groupId}/{userId}")
    @SendTo("/topic/im-server/{groupId}")
    public String send(  SendMsgParam param,
                       @DestinationVariable Integer type,
                       @DestinationVariable String groupId,
                       @DestinationVariable String userId){
        SendMsgParam.buildProperties(param,type, groupId, userId);
        redisPublisher.publish(param);
        return  param.getMessage();
    }
}

你可能感兴趣的:(java)