炫技亮点 Spring Websocket idle check原理

news/2025/1/18 10:56:22/

文章目录

    • 原理
    • 配置
    • 附件
      • Java_websocket空闲检测原理

Spring Websocket 是基于 WebSocket 协议的实现,它提供了一种在客户端和服务器之间实时双向通信的方式。其中,idle check(空闲检查)是一种机制,用于检测 WebSocket 连接的空闲状态。

Spring 框架本身并没有提供内置的主动发送 Ping 消息的机制。WebSocket 协议本身定义了 Ping 和 Pong 消息用于心跳检测,但在 Spring 中,默认情况下并不会主动发送 Ping 消息。

其仅仅提供了定时的读写check,例如120秒内是否有读或者写。

Java_websocket提供了主动发送Ping消息的机制,原理在下面有。

原理

1.在第一次websocket 连接时,启动一个后台定时任务

org.apache.tomcat.websocket.BackgroundProcessManager.register

if (processes.size() == 0){wsBackgroundThread = new WsBackgroundThread();wsBackgroundThread.start();
}

2.其每秒执行一次,尝试去处理

org.apache.tomcat.websocket.BackgroundProcessManager

 private static class WsBackgroundThread extends Thread {@Overridepublic void run() {while (running) {try {Thread.sleep(1000);} catch (InterruptedException e) {// Ignore}manager.process();}} 

3.每秒调用一次backgroundProcess,当backgroundProcessCount>=10时继续处理

即等于每10秒check一次

org.apache.tomcat.websocket.WsWebSocketContainer.backgroundProcess

 public void backgroundProcess() {backgroundProcessCount++;if (backgroundProcessCount >= processPeriod) {backgroundProcessCount = 0;for (WsSession wsSession : sessions.keySet()) {wsSession.checkExpiration();}}

4.检查是否过期

org.apache.tomcat.websocket.WsSession.checkExpiration

protected void checkExpiration() {// Local copies to ensure consistent behaviour during method executionlong timeout = maxIdleTimeout;long timeoutRead = getMaxIdleTimeoutRead();long timeoutWrite = getMaxIdleTimeoutWrite();long currentTime = System.currentTimeMillis();String key = null;if (timeoutRead > 0 && (currentTime - lastActiveRead) > timeoutRead) {key = "wsSession.timeoutRead";} else if (timeoutWrite > 0 && (currentTime - lastActiveWrite) > timeoutWrite) {key = "wsSession.timeoutWrite";} else if (timeout > 0 && (currentTime - lastActiveRead) > timeout &&(currentTime - lastActiveWrite) > timeout) {key = "wsSession.timeout";}if (key != null) {String msg = sm.getString(key, getId());if (log.isDebugEnabled()) {log.debug(msg);}doClose(new CloseReason(CloseCodes.GOING_AWAY, msg), new CloseReason(CloseCodes.CLOSED_ABNORMALLY, msg));}}

配置

配置代码为container.setMaxSessionIdleTimeout(10 * 1000L);

整体示例如下

@Configuration
@EnableWebSocket // 启动Websocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler(), "/websocket/**")// 添加拦截器,可以获取连接的param和 header 用作认证鉴权.addInterceptors(new LakerSessionHandshakeInterceptor())// 设置运行跨域.setAllowedOrigins("*");}@Beanpublic ServletServerContainerFactoryBean createWebSocketContainer() {ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();// 设置默认会话空闲超时 以毫秒为单位 非正值意味着无限超时,默认值 0 ,默认没10s检查一次空闲就关闭container.setMaxSessionIdleTimeout(10 * 1000L);// 设置异步发送消息的默认超时时间 以毫秒为单位 非正值意味着无限超时 ,默认值-1,还没看到作用
//        container.setAsyncSendTimeout(10 * 1000L);// 设置文本消息的默认最大缓冲区大小 以字符为单位,默认值 8 * 1024container.setMaxTextMessageBufferSize(8 * 1024);// 设置二进制消息的默认最大缓冲区大小 以字节为单位,默认值 8 * 1024container.setMaxBinaryMessageBufferSize(8 * 1024);return container;}

附件

Java_websocket空闲检测原理

连接丢失检查是一种检测与另一个端点的连接是否丢失的功能,例如由于wifi或移动数据信号丢失。

为了检测丢失的连接,我们使用心跳实现。

检测以指定的时间间隔(例如:60 秒)运行,并对所有连接的端点执行以下操作:

  • 如果端点最近没有发送 pong,则断开端点。端点被给予 1.5 倍的时间间隔来回复PONG。因此,如果间隔为 60 秒,则端点有 90 秒的响应时间。
  • 向端点发送 ping。

检测是双向的,因此服务器可以检测到丢失的客户端,而客户端可以检测到与服务器的连接丢失。

端点应该在可行的情况下尽快用 Pong 帧响应 Ping 帧。

代码

// 设置间隔为120秒
server.setConnectionLostTimeout(120);
// 间隔小于或等于 0 的值会导致检查被停用。
server.setConnectionLostTimeout( 0 );

启动定时任务

if (this.connectionLostTimeout <= 0) {cancelConnectionLostTimer();return;
}
connectionLostCheckerFuture = connectionLostCheckerService.scheduleAtFixedRate(connectionLostChecker, connectionLostTimeout, connectionLostTimeout,TimeUnit.NANOSECONDS);

定时内容,check上传pong时间及发送Ping消息

 Runnable connectionLostChecker = new Runnable() {@Overridepublic void run() {// 实现原理 核心代码如下long minimumPongTime;synchronized (syncConnectionLost) {minimumPongTime = (long) (System.nanoTime() - (connectionLostTimeout * 1.5));}for (WebSocket webSocket : connections) {WebSocketImpl webSocketImpl = (WebSocketImpl) webSocket;if (webSocketImpl.getLastPong() < minimumPongTime) {// 如果最后一次收到PONG的时间差值 小于了 1.5倍的设置值// 则关闭连接log.trace("Closing connection due to no pong received: {}", webSocketImpl);webSocketImpl.closeConnection(CloseFrame.ABNORMAL_CLOSE)} else {// 为客户端发送Pingif (webSocketImpl.isOpen()) {webSocketImpl.sendPing();} else {log.trace("Trying to ping a non open connection: {}", webSocketImpl);}}}

http://www.ppmy.cn/news/630233.html

相关文章

老版三国演义片尾曲 历史的天空 歌词

《历史的天空》 暗淡了刀光剑影 远去了鼓角铮鸣 眼前飞扬着一个个 鲜活的面容 湮没了黄尘古道 荒芜了烽火边城 岁月啊你带不走 那一串串熟悉的姓名 兴亡谁人定啊 盛衰岂无凭啊 一页风云散啊 变幻了时空 聚散皆是缘哪 离合总关情啊 担当生前事啊 何计身后评 长江有意化作泪…

新包青天 片尾曲 参人生哲理

天外有天比你高 大富贵比不上身体好 无忧无虑平常心到老 看得透想得开别爱计较 宽宏大量开口笑 多朋友要比多仇人好 让人一步世界大多了 真心好 真意好 久了总会被看到 不需要急着让别人知道 重承诺 重感情 友谊才是宝 尝过人情冷暖最明了 现在讲谁傻瓜言之过早 人会好心有好报…

电视剧 片尾曲 王学兵 - 爱是一场等待

实际上这部电视剧在央视一套还没有演完&#xff0c;不错。讲述的是三对不同年龄段男女之间的爱情婚姻生活&#xff0c;有着坚持&#xff0c;有着忍耐&#xff0c;有着勇气&#xff0c;也有着放弃… <完美>堪称电视版的“20、30、40”。成功执导过《不要和陌生人说话》、《…

阿帕鲁萨镇片尾曲

阿帕鲁萨镇片尾曲 阿帕鲁萨镇片尾曲 值得推荐&#xff01;旋律可以 666

《白蛇传》观后感

央视一台刚结束的神话连续剧《白蛇传》&#xff0c; 看完后还是很有感觉的&#xff0c;heroine刘涛的表现也是很不错的。 我并非为影评人员&#xff0c;所以今日造次纯属娱乐&#xff0c;只是想纪念一下白素珍和许仙之间的坚贞不摧的爱情&#xff08;这是很难得 的&#xff09…

天乩之白蛇传说 全 集 百 度 云 网 盘 资 源

由杨紫、任嘉伦主演的古装神话偶像剧《天乩之白蛇传说》将于今晚20:00独家上线&#xff0c;该剧讲述了小白蛇白夭夭与药师宫宫上许宣前世今生、虐恋千年的爱情故事。剧中&#xff0c;杨紫饰演的白夭夭不仅呆萌可爱&#xff0c;更是为爱坚守千年&#xff0c;不改初心。而此前释出…

传统《白蛇传》与《白蛇传情》

《白蛇传情》剧本改编创作的思路&#xff0c;是回顾传统戏曲在《白蛇传》上的发展与演化。传统的汉田本《白蛇传》是以当时的社会冲破传统禁锢&#xff0c;围绕自由展开编写的&#xff0c;而《白蛇传情》主要围绕“情”&#xff0c;主要突出跨越种族的爱情&#xff0c;爱情戏曲…

心里话 心花放片尾曲

[ti:心里话(Daniel)][ar:][al:TVB"心花放"插曲][by:Daniel][01:19.12]陶大宇郭可盈陈豪廖碧儿 - 心里话 ("心花放"插曲)[01:22.73]曲&#xff1a;邓智伟 | [01:24.31]词&#xff1a;郑樱纶 [00:00.01]相信一个她[00:01.88]心爱一个她[00:03.58]不需要害…