Websocket issues related summary (Session sharing, multi-terminal user login, etc.)

Websocket problem when we use the fact that the main face session sharing problem:

Whether based on Websocket Spring implemented WebsocketSession

It is based on the JDK implementation of the Session

Or based netty also achieved ChannelHandlerContext

FIG using it will be described a scenario:

OK, I see this figure, almost should understand how they deal with the shared Session. In fact, the principle is very simple:

1, we know that there are nginx IP-holding function, in fact, this feature will be able to solve most of the scenes Session sharing problem. However, in some extreme cases still have problems, such as in the case of the same below the browser does not close a user to replace the condition of the network led to IP changed, or for some IP network is the case of changes, there will be Session the situation can not be found.

2, based on the above principles, we can optimize nginx, or single-instance storage. So time to operate, I tell all the service side, you go to the user's Session, and the message with the past. Then the corresponding user node to get the Session can be processed.

The above brief description about 2:00 the next Session of the principle of sharing, then there is such a scenario, the text may not be good expression, we use diagram to illustrate:

Generally appear to multiport circumstances should the above two cases, either allowed or not allowed. I am here to simply say the process flow impermissible.

Establish a connection when the first get older Session

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

 There is, then push to close the message, does not exist to inform other nodes to clear. Server node of course be excluded, where it is determined to over IP.

        if(oldSession!=null) {
            oldSession.getBasicRemote().sendObject(close);
        }else{
            //关闭其他节点的的session
            authService.pushCloseMessage(close);
        }
        //替换
        SOCK_MAP.put(baseStudentInfo.getId(),session);

Message listener

            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);
            }

Close method:

    /**
     * 关闭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("关闭连接异常");
            }
        }
    }

So basically to avoid problems multiport log, if multiport allowed to log in only when needed to change the storage, change to send a message to become mass.

He published 183 original articles · won praise 37 · views 160 000 +

Guess you like

Origin blog.csdn.net/zhuwei_clark/article/details/104772732