使用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM