zoukankan      html  css  js  c++  java
  • 使用spring事件完成消息推送功能

    需求是查询数据库 ,有无用户未读的消息,发消息通知前端。


    第一版:

    使用订阅者模式,一个线程轮询数据库是否有新消息,有则放入session属性中;一个线程拉,一直轮询这个session属性,有则通知前端。

      拉 :

     @OnOpen
        public String open(Session session) {
            Cache cache = cacheManager.getCache(EhCacheName.CONST);
    
            openSessions.add(session);if (session.getUserProperties().get("eventQueue")==null) {
                session.getUserProperties().put("eventQueue", new LinkedBlockingQueue());
            }
            if ( cache.get(session.getId() + "sentResponseForm")==null){
                cache.put(session.getId() + "sentResponseForm",new ArrayList<>());
            }
    
    
            if (!isEventOpen) {
            Thread eventQueuePoller = new Thread(() -> {
                //每一用户单独队列
                LinkedBlockingQueue queue = (LinkedBlockingQueue) session.getUserProperties().get("eventQueue");
                while (true) {
                    ResponseForm responseForm = (ResponseForm) queue.poll();
                    if (responseForm != null) {
                        session.getAsyncRemote().sendText(JSON.toJSONString(responseForm));
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            eventQueuePoller.setName("eventQueuePoller");
            eventQueuePoller.start();
    
            //判断
                new MessageListener(session, messageService, cacheManager).listen();
                isEventOpen = true;
            }
    
            return "open";
        }

      其中@OnMessage是J2EE websocket注解,ResponseForm 是自定义的数据格式 。

      推:轮询数据库,往队列里添加ResponseForm 。


    功能虽然能完成,可是存在问题:1.有新消息就一直往前端推送,直到消息被阅读,影响用户体验。2.无关代码放在一个功能里

    解决方法:

    第一个问题,使用缓存比对,即查询出来的和 缓存中比对,有新的才通知。

    第二个问题,使用spring自带的消息通知,其实在spring启动过程中已经使用过了,只是不知道。

    推的线程不变,但是不需要用户队列,取而代之得是

    ApplicationContext.publishEvent(event);

    然后所有实现了EventListener的类都会得到消息通知。


    从实现的角度 来说,区别就在于我通过一个队列订阅消息,可以并发往队列里加消息,而 spring的实现可以无需代码对多个订阅者通知。

    参考文章:https://jinnianshilongnian.iteye.com/blog/1902886

  • 相关阅读:
    不要抱怨网速慢,只怪你自己不会调快网速
    2014年6月27日 几何和排列 答案
    我的世界杯生活
    javascript设计模式--备忘录模式(Memento)
    翻译:AngularJS应用的认证技术
    javascript设计模式--状态模式(State)
    一张思维导图说明jQuery的AJAX请求机制
    数据库设计中的14个技巧
    密室经典逃脱N部--考验你的智力!据说全球没几人走出去!不要看攻略!【工作之余也来休闲一下】
    关于编程,大学没有传授的10件事
  • 原文地址:https://www.cnblogs.com/imjamin/p/10827885.html
Copyright © 2011-2022 走看看