Websocket 心跳检测:让您的应用程序免于意外断开连接 (websocket和http区别)
简介
WebSocket 是一个用于在浏览器和服务器之间进行全双工通信的高效协议。与 HTTP 请求不同,WebSocket 允许持久连接,使客户端和服务器可以实时交换消息。这种持续连接对于构建需要持续交互的应用程序(例如聊天应用程序、游戏和金融交易平台)至关重要。在某些情况下,WebSocket 连接可能会意外断开,导致应用程序行为不当或出现故障。为了解决这个问题,引入了心跳检测机制。心跳检测
心跳检测是一种机制,用于监控 WebSocket 连接的健康状况。它涉及客户端和服务器定期交换特殊消息(称为心跳消息),以验证连接是否仍然活跃。如果一段时间内未收到心跳消息,则认为连接已断开,应用程序可以采取适当的措施,例如重新连接或通知用户。实现
心跳检测可以通过多种方式实现。一种常见的方法是使用 JavaScript 定时器,该定时器定期向服务器发送心跳消息。服务器然后应答心跳消息,确认连接。 javascript // 客户端 const heartbeatInterval = 10000; // 每 10 秒发送一次心跳消息 let lastHeartbeat = new Date();setInterval(() => {const now = new Date();if (now - lastHeartbeat > heartbeatInterval) {// 发送心跳消息socket.send('{"type": "heartbeat"}');lastHeartbeat = now;} }, heartbeatInterval);// 服务器 socket.on('message', (message) => {if (message.type === 'heartbeat') {// 响应心跳消息socket.send('{"type": "heartbeat-response"}');} });频率
心跳消息的频率应根据应用程序的具体需求进行调整。对于需要高可靠性的应用程序,可能需要更频繁的心跳检测,例如每 1-2 秒一次。对于不太关键的应用程序,每 10-30 秒一次的心WebSocket心跳重连讲解
最近在开发小程序用到了WebSocket,小程序提供了相应的原生API,与H5的API使用方式上有一些区别,所以流行的H5的一些成熟的类库使用起来有些困难,而原生API又存在一些缺陷,所以就自己实现了一套心跳重连机制。 惯例,先简单介绍一下Websocket。 HTTP 协议是一种无状态的、无连接的、单向的应用层协议。 它采用了请求/响应模型。 通信请求只能由客户端发起,服务端对请求做出应答处理。 所以当我们想服务器主动给客户端发送消息,HTTP是做不到的,我们只能使用轮询或者长轮询来实现类似的功能,这样的方式效率低并且浪费资源,为了解决这样的问题,WebSocket诞生了。 把你给懒得!自己官网看去! 在使用原生WebSocket的时候,我们经常会感觉不太稳定,服务端发送的消息有时候客户端接收不到,或者是客户端发送的消息服务端接收不到,虽然WebSocket也提供了onError和onClose的方法,但是经常会有各种未知情况导致断开连接而并不触发Error或Close事件。 这样就导致实际连接已经断开了,而客户端和服务端却不知道,还在傻傻的等着消息来。 所以我们要解决的问题就很清晰了: 保证连接状态,连接断开时让客户端与服务端都能知道,进而重连。 页面载入后,我们连接socket先 然后调用initEventHandle来绑定各种各样的事件 这个先放在这我们一会往里填东西 我们设置一个锁和最大的重连次数,避免出现无限重连的情况,为了不给服务器太大的压力我这里设置的是5秒重试一次,最多请求12次。 改造一下initEventHandle这样我们就可以实现一般的触发Error的断线重连。 先撸为敬 心跳对象内timeout为每10秒发一次心跳,timeoutObj、serverTimeoutObj是清除定时器用的对象,reset方法重置定时器,start发送心跳。 继续改造我们的initEventHandle
一文吃透 WebSocket 原理
踩着年末的尾巴,提前布局来年,为来年的工作做个好的铺垫,所以就开始了面试历程,因为项目中使用到了WebSocket,面试官在深挖项目经验的时候,也难免提到WebSocket相关的知识点,因为之前并没有考虑这么深,所以,回答的还是有所欠缺,因此,赶紧趁热再熟悉熟悉,也借此机会,整理出来供大家咀嚼,每个项目都有其值得挖掘的闪光点,要用有爱的眼睛去发现。
WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。(维基百科)
WebSocket本质上一种计算机网络应用层的协议,用来弥补http协议在持久通信能力上的不足。
WebSocket 协议在2008年诞生,2011年成为国际标准。现在最新版本浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
WebSocket 的其他特点包括:
我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
因为 HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力。
举例来说,我们想了解查询今天的实时数据,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用轮询:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。
在WebSocket协议出现以前,创建一个和服务端进双通道通信的 web 应用,需要依赖HTTP协议,进行不停的轮询,这会导致一些问题:
http协议本身是没有持久通信能力的,但是我们在实际的应用中,是很需要这种能力的,所以,为了解决这些问题, WebSocket协议由此而生,于2011年被IETF定为标准RFC6455,并被RFC7936所补充规范。并且在HTML5标准中增加了有关WebSocket协议的相关api,所以只要实现了HTML5标准的客户端,就可以与支持WebSocket协议的服务器进行全双工的持久通信了。
WebSocket与HTTP的关系图:
下面一张图说明了 HTTP 与 WebSocket 的主要区别:
不同点:
与http协议一样,WebSocket协议也需要通过已建立的TCP连接来传输数据。具体实现上是通过http协议建立通道,然后在此基础上用真正WebSocket协议进行通信,所以WebSocket协议和http协议是有一定的交叉关系的。首先,WebSocket是一个持久化的协议,相对于 HTTP 这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的 PHP 生命周期来解释。
HTTP 的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次 HTTP 请求就结束了。
在 HTTP1.1 中进行了改进,使得有一个 keep-alive,也就是说,在一个 HTTP 连接中,可以发送多个 Request,接收多个 Response。但是请记住 Request = Response, 在 HTTP 中永远是这样,也就是说一个 Request 只能有一个 Response。而且这个 Response 也是被动的,不能主动发起。首先 WebSocket 是基于 HTTP 协议的,或者说借用了 HTTP 协议来完成一部分握手。
首先我们来看个典型的 WebSocket 握手
熟悉 HTTP 的童鞋可能发现了,这段类似 HTTP 协议的握手请求中,多了这么几个东西。
这个就是WebSocket的核心了,告诉Apache 、 Nginx等服务器:注意啦,我发起的请求要用WebSocket协议,快点帮我找到对应的助理处理~而不是那个老土的HTTP。
这里开始就是 HTTP 最后负责的区域了,告诉客户,我已经成功切换协议啦~
依然是固定的,告诉客户端即将升级的是 WebSocket 协议,而不是mozillasocket ,lurnarsocket或者shitsocket 。
然后,Sec-WebSocket-Accept这个则是经过服务器确认,并且加密过后的Sec-WebSocket-Key 。服务器:好啦好啦,知道啦,给你看我的 ID CARD 来证明行了吧。后面的,Sec-WebSocket-Protocol则是表示最终使用的协议。至此,HTTP 已经完成它所有工作了,接下来就是完全按照WebSocket协议进行了。总结,WebSocket连接的过程是:
优点:
缺点:
心跳就是客户端定时的给服务端发送消息,证明客户端是在线的, 如果超过一定的时间没有发送则就是离线了。
当客户端第一次发送请求至服务端时会携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果不存在就存入db或者缓存中, 第二次客户端定时再次发送请求依旧携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果存在就把上次的时间戳拿取出来,使用当前时间戳减去上次的时间, 得出的毫秒秒数判断是否大于指定的时间,若小于的话就是在线,否则就是离线;
通过查阅资料了解到 nginx 代理的 websocket 转发,无消息连接会出现超时断开问题。网上资料提到解决方案两种,一种是修改nginx配置信息,第二种是websocket发送心跳包。下面就来总结一下本次项目实践中解决的websocket的断线 和 重连 这两个问题的解决方案。主动触发包括主动断开连接,客户端主动发送消息给后端
主动断开连接,根据需要使用,基本很少用到。
下面主要讲一下客户端也就是前端如何实现心跳包:
首先了解一下心跳包机制
跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项: SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。
心跳检测步骤:
针对这种异常的中断解决方案就是处理重连,下面我们给出的重连方案是使用js库处理:引入 ,ws建立链接方法使用js库api方法:
断网监测支持使用js库:
以上方案,只是抛砖引玉,如果大家有更好的解决方案欢迎评论区分享交流。
WebSocket 是为了在 web 应用上进行双通道通信而产生的协议,相比于轮询HTTP请求的方式,WebSocket 有节省服务器资源,效率高等优点。WebSocket 中的掩码是为了防止早期版本中存在中间缓存污染攻击等问题而设置的,客户端向服务端发送数据需要掩码,服务端向客户端发送数据不需要掩码。WebSocket 中 Sec-WebSocket-Key 的生成算法是拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码。WebSocket 协议握手是依靠 HTTP 协议的,依靠于 HTTP 响应101进行协议升级转换。
HTTP amp;WebSocket有什么区别,它们的运行机制是怎样的
定时发送消息,服务器收到请求以后马上回复。 称为轮询定时发送消息,服务器收到请求以后先不回复,自己判断一下是不是必要,不必要回复就等着【比如这个时候没有消息】,这时client会按照响应中的处理方法处理,一般就是等着。 当服务器内部逻辑觉得有必要回复的时候【一般是有消息了】再回复。 叫做长轮询3.使用iframe页面维持一个长连接,服务器不断发送数据。 4.使用flash
若对本页面资源感兴趣,请点击下方或右方图片,注册登录后
搜索本页相关的【资源名】【软件名】【功能词】或有关的关键词,即可找到您想要的资源
如有其他疑问,请咨询右下角【在线客服】,谢谢支持!
相关文章
- 网络游戏潮流风向标!2021 年 10 款不可错过的网络游戏,让你领略游戏未来 (网络游戏流行语)
- 跨平台联机畅玩!2021 年 10 款支持多平台游戏的网络游戏,拉上好友一起战斗 (跨平台联机游戏什么意思)
- 世界级图形盛宴!2021 年 10 款视觉震撼的网络游戏,让你身临其境 (世界著名图形)
- 角色扮演冒险之旅!2021 年 10 款引人入胜的网络游戏,让你化身传奇 (角色扮演冒险游戏)
- 多人对战激战!2021 年 10 款最具竞争力的网络游戏,考验你的策略性 (多人对战激战怎么玩)
- 网络游戏革命!2021 年 10 款创新性网络游戏,重新定义游戏体验 (游戏革命官网)
- 独家抢先体验:2021 年 10 款即将推出的网络游戏,让你拭目以待 (独家抢先体验黑暗欺骗重制版第一关)
- 快节奏、身临其境:2021 年 10 款激爽网络游戏让你肾上腺素飙升 (快节奏生)
- 踏入虚拟世界!2021 年不容错过的 10 款最热门网络游戏 (踏入虚拟世界小说)
- 2021 年不容错过的网络游戏大作,让你激动不已 (2021年不忘初心牢记使命主题教育活动)
发表评论
评论列表
- 这篇文章还没有收到评论,赶紧来抢沙发吧~