Websocket相關問題總結(Session共享,用戶多端登錄等)

我們在使用websocket的時候其實主要面對的問題就是session共享的問題:

不管是基於Spring實現的Websocket的WebsocketSession

還是基於JDK實現的Session

亦或者基於netty實現的ChannelHandlerContext

用圖來描述下場景吧:

OK,大家看到這個圖了,差不多應該明白了Session共享應該怎麼處理了。其實原理很簡單:

1、我們知道nginx有IP保持的功能,其實這個功能就能解決大部分場景的Session共享問題。 但是某些極限情況下還是會有問題,比如在瀏覽器沒有關閉的情況下同一個用戶更換了網絡的情況導致IP變了,或者對於某些網絡的IP是變動的情況下,就會出現Session找不到的情況。

2、基於上述nginx的原理我們可以進行優化,還是單例存儲。那麼要操作的時候,我告訴所有的服務端,你們去找這個用戶的Session,並把消息帶過去。那麼相應的節點根據用戶拿到Session了就可以進行處理了。

上面2點大概簡單的描述了下Session共享的原理,那麼有這麼個場景,文字可能不太好表達,我們還是用圖來說明:

一般出現多端情況也應該就上面2種情況,要麼允許,要麼不允許。我這裏簡單的說下不允許的處理流程。

建立連接的時候,先獲取老的Session

 Session oldSession = SOCK_MAP.get(baseStudentInfo.getId());

 存在,則推送關閉消息,不存在告知其他節點去清楚。當然本節點的的Server要排除在外,這裏就通過IP判斷即可。

        if(oldSession!=null) {
            oldSession.getBasicRemote().sendObject(close);
        }else{
            //關閉其他節點的的session
            authService.pushCloseMessage(close);
        }
        //替換
        SOCK_MAP.put(baseStudentInfo.getId(),session);

消息監聽

            String serverIp = IPUtils.getLocalhostIp();
            logger.info("當前IP:"+serverIp);
            logger.info("content的IP:"+wsMessage.getBody().getContent());
            //IP不相等,說明不是當前連接的服務端,關閉其他端口
            if(!serverIp.equals(wsMessage.getBody().getContent())){
                //關閉session,並返回給前端
                customerHandler.closeSession(wsMessage.getBody().getReceiver(), wsMessage);
            }

關閉的方法:

    /**
     * 關閉Session
     * @param studentId
     * @param closeMessage
     */
    public void closeSession(Long studentId,WsMessage closeMessage){
        Session session = SOCK_MAP.get(studentId);
        if(session!=null) {
            try {
                session.getBasicRemote().sendObject(closeMessage);
                SOCK_MAP.remove(studentId);
                //清除redis
                logger.info("連接已關閉:" + studentId);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("關閉連接異常");
            }
        }
    }

這樣基本就避免多端登錄的問題,如果允許多端登錄的時候只需要更改存儲,更改發送消息變成羣發即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章