websocket stomp连接一段时间后断开

背景概述

因为项目中存在频繁的由服务器发起的数据交换,相比使用Ajax轮训的方式,websocket长连接和双向保持的特点能够较好的提升数据交换的性能。
为了简便,直接使用spring boot + shiro + stomp和socketJs作为构建的工具。
但是由于使用时,主要是由服务端进行数据的推送,通过stomp自行保持心跳,就会存在session过期导致连接断开的情况,而且由于stomp本身不会提示错误原因,导致排查起来比较麻烦,因此记录下整个纠错过程以备忘。

原因排查

1. 问题现象:

在一开始打开时,一切正常,数据能推送成功,但是在大约10分钟左右(时长不定)能通过chrome的前端调试工具发现stomp提示连接断开。服务器端无任何异常提示。

2. 原因排查:

因为服务器端无任何异常,且断连时长不定,因此推测为可能是session导致的自动断链或者心跳丢失导致的。因为stomp本身不会报错误原因,因此想要找到具体的错误原因比较麻烦。后来发现可以通过断点到stomp的onclose时间就能够获取到具体的错误码,这就为我们定位问题提供了很好的帮助(具体断点位置如下图所示)


error code.PNG
3. 问题确定

最后通过错误码发现,提示的错误码是1008,reason部分提示的是http session被关闭,因此问题就比较清楚了,是由于session释放导致的断链。这一点就很有意思,因为在使用过程中为了避免不必要的数据传输就一直没有发起websocket的send事件,只是一直在subscribe监听服务器的推送。因此导致了服务器的session一直没有被touch(),从而释放。(其实个人觉得这个可能也是一个比较有意思的问题,为什么心跳没有被处理会触发到session,具体没有试验是不是和我使用了shiro的session作为管理有关,有兴趣的同学们可以尝试一下)
这里也顺便贴上对于错误码的描述和相关参考资料,便于大家解决其它的错误码问题:

  1. 首先关于1008 错误错误码的描述如下 Java WebSocket 规范

如果用户退出了包含的web应用,或如果身份验证超时,或由于其他一些原因无效的。在这种情况下,websocket实现必须立即使用websocket关闭状态码1008关闭连接

  1. 关于错误码的具体原因 WebSocket Protocol
all code.PNG
4. 问题解决

那么问题找到了响应的解决方案就比较好处理了,但是究竟哪种方案比较好,还是得看具体的业务需求和对利弊的取舍。

  1. 可以通过修改session的过期时间来控制连接的时长(但是可能没有那么精准),如果为了简便以可以设置为永远不过期(但是永远不过期有很多潜在问题)。笔者主要使用了shiro作为session的管理工具,设置session不过期的代码如下:
Subject currentUser = SecurityUtils.getSubject(); 
Session session = currentUser.getSession();
 //注意这里单位为ms,且会向s向下取整
session.setTimeout(-1000); 
  1. 通过服务器端主动发送send前,手动调用一下session的touch()函数,但是这种方法感觉比较不合理,而且需要注意send和touch的顺序关系,不然容易报response已经commit后再重建session的异常
Subject currentUser = SecurityUtils.getSubject(); 
Session session = currentUser.getSession();
session.touch();
//注意顺序
messagingTemplate.convertAndSend(desUrl, value);
  1. 周期性通过客户端发送一个send消息到服务器,维持session的不过期。这个方案实现比较简单,而且对服务器的影响较小,唯一不爽的一点是感觉有点违背了当时服务器推送的初衷(毕竟已经发送心跳保持激活了,还再发送send有点多此一举的感觉),不过综合考虑到实际处理中笔者可以通过send来帮助控制及时取消掉一些observer的订阅,因此最后选择了这个方案。
       function listenInfo(){
            var listenUrl = "/queue/xxx/" ;
            stompClient.subscribe(listenUrl, function (data) {  
                setChangedAccount(data);                
                var currentDate = new Date();
                //50s send once(server expire is 60s)
                if((currentDate.getTime()-lastSendDate.getTime())>=50000){      
                    sendInfo(userID);
                    lastSendDate = new Date();
                }
            });    
        }

结语

问题本身倒是不复杂,就是对stomp不熟悉,确定具体的错误原因上花了很多时间,进行了很多白费的尝试,所以希望能记录下,做个以后的备忘,防止再走很多弯路。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来...
    谁在烽烟彼岸阅读 2,918评论 1 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 摘要 STOMP是一个简单的可互操作的协议, 被用于通过中间服务器在客户端之间进行异步消息传递。它定义了一种在客户...
    Leon622阅读 21,949评论 3 7
  • 圈子,古已有之,“一朝天子一朝臣”怎么说的?不就是皇帝是大老板,顺我者昌,逆我者亡嘛。在同一朝庭之上,还有因政见不...
    非常道_faae阅读 541评论 0 5
  • 听说有一个理论叫一万小时天才理论,就是你在某方面花费的时间达到一万小时,很容易成为该专业或该项目的天才级别人物。很...
    如果我是壹只猫阅读 287评论 0 0