实现WebSocket心跳机制,以及超过30分钟无活动自动关闭会话的功能

实现WebSocket心跳机制,以及超过30分钟无活动自动关闭会话的功能,涉及到后端和前端的协作。下面分别介绍后端(使用Spring WebFlux)和前端如何实现这一机制。

后端实现(Spring WebFlux)

在Spring WebFlux中,你可以定期发送心跳消息(例如,使用ping消息)来维持连接。同时,你需要追踪最后一次活动时间,如果超过30分钟无活动,则关闭会话。

  1. 心跳消息发送

WebSocketHandler的实现中,你可以通过定时发送ping消息来实现心跳。使用Flux.interval创建一个定期执行的Flux,并发送ping消息。

java 复制代码
@Override
public Mono<Void> handle(WebSocketSession session) {
    Flux<WebSocketMessage> heartBeat = Flux.interval(Duration.ofSeconds(15))  // 每15秒发送一次心跳
            .map(tick -> session.pingMessage(DataBufferFactory -> DataBufferFactory.allocateBuffer(0)));

    Mono<Void> output = session.send(heartBeat);

    Mono<Void> input = session.receive()  // 处理接收到的消息
            .doOnNext(message -> {
                // 更新最后活动时间
            })
            .then();

    return Mono.zip(input, output).then();
}
  1. 活动追踪和超时处理

你可以定义一个变量来追踪最后一次活动时间。每次接收到消息时更新这个时间。同时,你可以使用一个定时器来检查是否已经超过30分钟无活动。

java 复制代码
AtomicLong lastActivityTime = new AtomicLong(System.currentTimeMillis());

Flux<WebSocketMessage> timeoutChecker = Flux.interval(Duration.ofMinutes(1))
    .flatMap(tick -> {
        long inactiveDuration = System.currentTimeMillis() - lastActivityTime.get();
        if (inactiveDuration > Duration.ofMinutes(30).toMillis()) {
            // 超过30分钟无活动,可以关闭会话
            return Flux.just(session.close(CloseStatus.NORMAL.withReason("Inactive for more than 30 minutes")));
        } else {
            return Flux.empty();  // 无操作
        }
    });

Mono<Void> output = session.send(Flux.merge(heartBeat, timeoutChecker));

前端实现

前端需要实现两部分逻辑:一是响应心跳消息,二是处理连接超时关闭。

  1. WebSocket心跳响应

前端WebSocket客户端需要能够处理后端发送的心跳ping消息,并据此保持连接。

javascript 复制代码
let socket = new WebSocket("ws://example.com/ws");
socket.onmessage = function(event) {
    // 处理服务器发送的消息
};

// 处理Ping消息,维持连接
socket.onping = function(event) {
    // 可以发送Pong消息回应,或不做任何操作
};
  1. 超时关闭处理

前端还需要能够处理超过30分钟无数据交换时的情况。这通常通过设置一个定时器实现,每次收到消息时重置定时器。

javascript 复制代码
let timeoutInterval = 30 * 60 * 1000;  // 30分钟
let timeoutTimer;

function resetTimeout() {
    clearTimeout(timeoutTimer);
    timeoutTimer = setTimeout(() => {
        socket.close();
        alert("WebSocket closed due to inactivity.");
    }, timeoutInterval);
}

socket.onopen = resetTimeout;
socket.onmessage = resetTimeout;
socket.onping = resetTimeout;  // 如果前端能收到ping消息,也应重置定时器

通过上述方法,你可以在客户端和服务器之间实现一个心跳机制,以及在超过一定时间无活动时自动关闭WebSocket连接的功能。

相关推荐
二DUAN帝2 小时前
UE实现路径回放、自动驾驶功能简记
人工智能·websocket·机器学习·ue5·自动驾驶·ue4·cesiumforue
2501_915918413 小时前
iPhone 抓包工具有哪些?多工具对比分析优缺点
websocket·网络协议·tcp/ip·http·网络安全·https·udp
工控小楠3 小时前
Modbus TCP转Profinet网关实现视觉相机与西门子PLC配置实例研究
modbustcp·网络协议·tcp/ip·profinet
半路_出家ren3 小时前
传输层协议TCP、UDP
网络协议·tcp/ip·udp·tcp
小何学计算机5 小时前
HTTPS工作原理
网络协议·http·https
游戏开发爱好者87 小时前
iOS 出海 App 安全加固指南:无源码环境下的 IPA 加固与防破解方法
websocket·网络协议·tcp/ip·http·网络安全·https·udp
2501_915921437 小时前
苹果App上架流程:不用Mac也可以上架的方法
websocket·网络协议·tcp/ip·http·网络安全·https·udp
阿沁QWQ7 小时前
UDP的socket编程
网络·网络协议·udp
paopaokaka_luck8 小时前
智能推荐社交分享小程序(websocket即时通讯、协同过滤算法、时间衰减因子模型、热度得分算法)
数据库·vue.js·spring boot·后端·websocket·小程序
沐尘而生9 小时前
【AI智能体】智能音视频-硬件设备基于 WebSocket 实现语音交互
大数据·人工智能·websocket·机器学习·ai作画·音视频·娱乐