• redis订阅/发布


    redis订阅发布实现是通过类似于Map<Key,List>这样的数据结构,使用subscribe监听某个channel(通道)也就是key,然后将自己加入对应Key的list中,当有publish命令将msg推送到对应的channel中时,遍历对应的list,发送数据。这是redis实现的原理。说说java中redis订阅发布我看到的吧!

    我们需要创建消息监听器容器,然后将消息监听器与相应的消息订阅处理器绑定,其中消息监听适配器需通过反射指定对应的处理方法,在容器中消息订阅器订阅的时Key(这里我用枚举来处理),然后创建发布者和监听者对应的方法就可以了

    1.创建对应的key值

    /**
     * @Auther: eros
     * @Date: 2019/2/27 15:43
     * @Description:
     * 发布/订阅 key 枚举
     */
    public enum WebSocketContent {
    
        WS_EVENT_TYPE,
        WS_EVENT_DEV,
        WS_EVENT_DEV_VERSION;
    
    }

    2.配置redis消息监听器

    因为目前页面上有三个数据需要后台websocket进行传输,所以绑定了三个消息监听器和相应的消息订阅处理器,这里没有添加redisTemplate,根据自己的需要添加相对应的

        /* =================================== redis listener =================================== */
    
        /**
         * redis消息监听器容器
         * 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
         * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
         * @param connectionFactory
         * @param listenerAdapter_dev
         * @param listenerAdapter_type
         * @param listenerAdapter_dev_version
         * @return
         */
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                MessageListenerAdapter listenerAdapter_dev,
                                                MessageListenerAdapter listenerAdapter_type,
                                                MessageListenerAdapter listenerAdapter_dev_version) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            //可以添加多个 messageListener
            container.addMessageListener(listenerAdapter_dev, new PatternTopic(WebSocketContent.WS_EVENT_DEV.name()));
            container.addMessageListener(listenerAdapter_dev_version, new PatternTopic(WebSocketContent.WS_EVENT_DEV_VERSION.name()));
            container.addMessageListener(listenerAdapter_type, new PatternTopic(WebSocketContent.WS_EVENT_TYPE.name()));
            return container;
        }
    
        /**
         * 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法
         * @param redisReceiver
         * @return
         */
        @Bean(name = "listenerAdapter_dev")
        public MessageListenerAdapter listenerAdapterDev(RedisReceiverService redisReceiver) {
            return new MessageListenerAdapter(redisReceiver, "receiveMessageByDev");
        }
    
    
        /**
         * @param redisReceiver
         * @return
         */
        @Bean(name = "listenerAdapter_type")
        public MessageListenerAdapter listenerAdapterType(RedisReceiverService redisReceiver) {
            return new MessageListenerAdapter(redisReceiver, "receiveMessageByType");
        }
    
    
        /**
         * @param redisReceiver
         * @return
         */
        @Bean(name = "listenerAdapter_dev_version")
        public MessageListenerAdapter listenerAdapterDevVersion(RedisReceiverService redisReceiver) {
            return new MessageListenerAdapter(redisReceiver, "receiveMessageByDevVersion");
        }

    3.创建发布者,需要发布数据的地方都是用这一个接口

    /**
     * @Auther: eros
     * @Date: 2019/2/27 15:37
     * @Description: 发布者
     */
    @Service
    public class RedisPublisherService {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(RedisPublisherService.class);
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * @auther: eros
         * @param content 发布类型
         * @param message 发布消息
         * @date: 2019/2/27 16:04
         * @description
         * @return: void
         */
        public void sendMessage(WebSocketContent content,String message) {
            LOGGER.info("》》》》》》》》》》》》》》》》》》》》》》》
    ");
            LOGGER.info("发布信息");
            try {
                redisTemplate.convertAndSend(content.name(), message);
                LOGGER.info("发布成功");
                LOGGER.info("《《《《《《《《《《《《《《《《《《《《《《《
    ");
            } catch (Exception e) {
                e.printStackTrace();
                LOGGER.info("发布失败");
                LOGGER.info("《《《《《《《《《《《《《《《《《《《《《《《
    ");
            }
        }
    
    }

    4.创建对应的处理器,这里与上次写的websocket配套使用

    /**
     * @Auther: eros
     * @Date: 2019/2/27 16:01
     * @Description:
     */
    @Service
    public class RedisReceiverService{
    
        private static Logger LOGGER = LoggerFactory.getLogger(RedisReceiverService.class);
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * @param message
         */
        public void receiveMessageByDev(String message) {
            message = message.substring(message.indexOf("["));
            LOGGER.info("收到的mq消息 %s - %s" ,WebSocketContent.WS_EVENT_DEV,message);
            sendMessage(WebSocketContent.WS_EVENT_DEV +":" + JSON.toJSONString(message));
        }
    
        /**
         * @param message
         */
        public void receiveMessageByType(String message) {
            message = message.substring(message.indexOf("["));
            LOGGER.info("收到的mq消息 %s - %s" ,WebSocketContent.WS_EVENT_TYPE,message);
            sendMessage(WebSocketContent.WS_EVENT_TYPE +":" + JSON.toJSONString(message));
        }
    
        /**
         * @param message
         */
        public void receiveMessageByDevVersion(String message) {
            message = message.substring(message.indexOf("["));
            LOGGER.info("收到的mq消息 %s - %s" ,WebSocketContent.WS_EVENT_DEV_VERSION,message);
            sendMessage(WebSocketContent.WS_EVENT_DEV_VERSION +":" + JSON.toJSONString(message));
        }
    
        /**
         * @auther: eros
         * @param message 1
         * @date: 2019/2/27 16:22
         * @description 发送信息
         * @return: void
         */
        private void sendMessage(String message){
            Map<String,ChatRoomServerEndpoint> sessionMap = ChatRoomServerEndpoint.getSessionMap();
            for(Map.Entry<String,ChatRoomServerEndpoint> entries : sessionMap.entrySet()){
                LOGGER.info("content:ip - {} 获取",entries.getKey());
                ChatRoomServerEndpoint webSocketServer = entries.getValue();
                try {
                    webSocketServer.getSession().getBasicRemote().sendText(message);
                } catch (IOException e) {
                    LOGGER.error("JSON转换有问题");
                    e.printStackTrace();
                }
            }
        }
    
    }
  • 相关阅读:
    组合模式
    数据去重
    combiner
    合并文档
    对象锁 区别 类锁
    一个简单的死锁示例
    线程安全的单例模式
    线程安全与不安全(误解)
    tf.nn.max_pool 池化
    tf.nn.depthwise_conv2d 卷积
  • 原文地址:https://www.cnblogs.com/kongkongFabian/p/10448938.html
Copyright © 2020-2023  润新知