websocket在后端如何判断在线离线

websocket在后端如何判断用户的在线离线,前端需要给我传哪些参数

我的理解:
在线就是登录成功嘛, 那肯定要传token, token不为空 就是在线了

离线 , 用户长时间无操作就自动离线?

websocket 要个锤锤的token

望采纳!!!

在org.springframework.web.reactive.socket.WebSocketHandler中实现一个关闭事件:

public Mono<Void> handle(final WebSocketSession session) {
    final String sessionId = session.getId();
    if(sessions.add(sessionId)) {
        LOG.info("Starting WebSocket Session [{}]", sessionId);
        WebSocketMessage msg = session.textMessage(String.format("{\"session\":\"%s\"}", sessionId));
        final Flux<WebSocketMessage> outFlux = Flux.concat(Flux.just(msg), newMetricFlux.map(metric -> {
            LOG.info("Sending message to client [{}]: {}", sessionId, metric);
            return session.textMessage(metric);             
        }));
        session.receive().doFinally(sig -> {
            LOG.info("Terminating WebSocket Session (client side) sig: [{}], [{}]", sig.name(), sessionId);
            session.close();
            sessions.remove(sessionId); 
        }).subscribe(inMsg -> {
            LOG.info("Received inbound message from client [{}]: {}", sessionId, inMsg.getPayloadAsText());
        });
        return session.send(outFlux);
    }
    return Mono.empty();
}

前端都是可以监听到的吧?退出程序什么的, 然后后端在写一个一定时间就确定一下是否离线

后端websocket服务采用那个框架?每个websocket连接后都是有个通道缓存在我们服务中,客户端断连是会触发事件或者心跳机制不通过也可以,目前这里采用netty,下面的channelInactive方法


public class NettyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {



    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof WebSocketServerProtocolHandler.HandshakeComplete){
            log.info("websocket协议握手成功");
            GlobalChannel globalChannel = SpringContextUtil.getBeanByClass(GlobalChannel.class);
            AttributeKey<String> tokenKey = globalChannel.getTokenKey();
            String userId = ctx.channel().attr(tokenKey).get();
            if(StringUtils.isBlank(userId)){
                log.info(NettyWebSocketHandler.class+"非法连接");
                ctx.writeAndFlush(new TextWebSocketFrame("非法连接")).addListener(ChannelFutureListener.CLOSE);
            }else {
                globalChannel.bindChannel(userId,ctx.channel());
            }
        }else {
            super.userEventTriggered(ctx,evt);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("webSocket连接,通道开启,id:{}", ctx.channel().id());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("webSocket断开连接,通道关闭,id:{}", ctx.channel().id());
        GlobalChannel globalChannel = SpringContextUtil.getBeanByClass(GlobalChannel.class);
        Attribute<String> attr = ctx.channel().attr(globalChannel.getTokenKey());
        if (null != attr && null != attr.get()){
            String userId = attr.get();
            globalChannel.removeChannel(userId);
            attr.remove();
            log.info("{}用户连接通道移除",userId);
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame webSocketFrame) throws Exception {
        log.info(((TextWebSocketFrame) webSocketFrame).text());
        channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("dfsffsf"));
    }
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^