WebSocket 的理解
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
其他特点包括:
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
ws://xncoding.com:80/some/path
另外客户端不只是浏览器,只要实现了ws或者wss协议的客户端socket都可以和服务器进行通信。
websocket协议
Websocket其实是一个新协议,借用了HTTP的协议来完成一部分握手,只是为了兼容现有浏览器的握手规范而已。
一个典型的Websocket握手(借用Wikipedia)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
其中的
Upgrade: websocket
Connection: Upgrade
这个就是Websocket的核心了,告诉Apache、Nginx等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。
服务器返回:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了。
TCP长连接与超时
什么是长连接
先说短连接, 短连接是通讯双方有数据交互时就建立一个连接, 数据发送完成后,则断开此连接。
长连接就是大家建立连接之后, 不主动断开. 双方互相发送数据, 发完了也不主动断开连接, 之后有需要发送的数据就继续通过这个连接发送。

TCP连接在默认的情况下就是所谓的长连接, 也就是说连接双方都不主动关闭连接, 这个连接就应该一直存在。
但是网络中的情况是复杂的, 这个连接可能会被切断. 比如客户端到服务器的链路因为故障断了, 或者服务器宕机了, 或者是你家网线被人剪了, 这些都是一些莫名其妙的导致连接被切断的因素, 还有几种比较特殊的。
NAT超时
因为IPv4地址不足, 或者我们想通过无线路由器上网, 我们的设备可能会处在一个NAT设备的后面, 生活中最常见的NAT设备是家用路由器。
NAT设备会在IP封包通过设备时修改源/目的IP地址。对于家用路由器来说, 使用的是网络地址端口转换(NAPT), 它不仅改IP, 还修改TCP和UDP协议的端口号, 这样就能让内网中的设备共用同一个外网IP。举个例子, NAPT维护一个类似下表的NAT表:

NAT设备会根据NAT表对出去和进来的数据做修改, 比如将 192.168.0.3:8888 发出去的封包改成 120.132.92.21:9202 , 外部就认为他们是在和 120.132.92.21:9202 通信。同时NAT设备会将 120.132.92.21:9202 收到的封包的IP和端口改成192.168.0.3:8888 , 再发给内网的主机, 这样内部和外部就能双向通信了, 但如果其中 192.168.0.3:8888 == 120.132.92.21:9202 这一映射因为某些原因被NAT设备淘汰了, 那么外部设备就无法直接与 192.168.0.3:8888 通信了。
我们的设备经常是处在NAT设备的后面, 比如在大学里的校园网, 查一下自己分配到的IP, 其实是内网IP, 表明我们在NAT设备后面, 如果我们在寝室再接个路由器, 那么我们发出的数据包会多经过一次NAT。
国内移动无线网络运营商在链路上一段时间内没有数据通讯后, 会淘汰NAT表中的对应项, 造成链路中断。
网络状态切换
手机网络和WIFI网络切换, 网络断开和连上等情况, 也会使长连接断开. 这里原因可能比较多, 但结果无非就是IP变了, 或者被系统通知连接断了。
心跳包的作用
网上很多文章介绍长连接的时候都说:
- 因为是长连接, 所以需要定期发送心跳包。
- 心跳包是用来通知服务器客户端当前状态。
提出这些说法的人其实自己也是一知半解. 这些说法其实都对, 但是没有答到点上。
明确一点, TCP长连接本质上不需要心跳包来维持, 大家可以试一试, 让两台电脑连上同一个wifi, 然后让其中一台做服务器, 另一台用一个普通的没有设置KeepAlive的Socket连上服务器, 只要两台电脑别断网, 路由器也别断电, DHCP正常续租, 就这么放着, 过几个小时再用其中一台电脑通过之前建立的TCP连接给另一台发消息, 另一台肯定能收到。
那为什么要有心跳包呢? 其实主要是为了防止上面提到的NAT超时, 既然一些NAT设备判断是否淘汰NAT映射的依据是一定时间没有数据, 那么客户端就主动发一个数据。
心跳包必须由客户端发送, 客户端发现连接断了, 还可以尝试重连服务器。
所以心跳包的主要作用是防止NAT超时, 其次是探测连接是否断开。
链路断开, 没有写操作的TCP连接是感知不到的, 除非这个时候发送数据给服务器, 造成写超时, 否则TCP连接不会知道断开了。主动kill掉一方的进程, 另一方会关闭TCP连接, 是系统代进程给服务器发的FIN。TCP连接就是这样, 只有明确的收到对方发来的关闭连接的消息, 或者自己意识到发生了写超时, 否则它认为连接还存在。
心跳包的时间间隔
每次发送心跳都会消耗电量和网络流量,那么控制心跳包的时间间隔就显得非常重要了。
现实是残酷的, 根据网上的一些说法, 中移动2/3G下, NAT超时时间为5分钟, 中国电信3G则大于28分钟, 理想的情况下, 客户端应当以略小于NAT超时时间的间隔来发送心跳包。
关于如何让心跳间隔逼近NAT超时的间隔, 同时自动适应NAT超时间隔的变化, 可以参看 《移动端IM实践:实现Android版微信的智能心跳机制》
服务器如何处理心跳包
如果客户端心跳间隔是固定的, 那么服务器在连接闲置超过这个时间还没收到心跳时, 可以认为对方掉线, 关闭连接。如果客户端心跳会动态改变, 如上节提到的微信心跳方案, 应当设置一个最大值, 超过这个最大值才认为对方掉线。
还有一种情况就是服务器通过TCP连接主动给客户端发消息出现写超时, 可以直接认为对方掉线。
服务器框架
服务器端实现了websocket协议的框架有很多,比如Netty、Undertow、Jetty、Socket.IO等等,通过性能测试发现Netty表现最好,内存占用非常的少,CPU使用率也不高,尤其内存占用,远远小于其它框架。
客户端框架
浏览器端可选择很多,最著名的的就是 Socket.IO
Android端的也很多,包括 Socket.IO、 okhttp等等。
WebSocket 的理解的更多相关文章
- WebSocket协议理解-数据包格式解析
WebSocket 的诞生 做客户端开发时,接触最多的应用层网络协议,就是 HTTP 协议,而今天介绍的 WebSocket,下层和 HTTP 一样也是基于 TCP 协议,这是一种轻量级网络通信协议, ...
- websocket的理解及实例应用
websocket协议是HTML5提出的一个新的规范,主要用于实现服务器及时推送信息给客户端的功能. websocket实现是基于HTTP协议的部分握手功能,但是websocket仅仅握手一次即可进行 ...
- websocket简单理解
实现及原理 Websocket是一种在单个TCP连接上进行全双工通讯的协议. WebSocket 首先发起一个 HTTP 请求,在请求头加上 `Upgrade` 字段,该字段用于改变 HTTP 协议版 ...
- websocket个人理解总结
WebSocket 释义:聊天室.服务.套接字.协议 引用:https://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/index ...
- WebSocket的理解
Websocket相对于无状态的HTTp协议,是在一次成功连接之后,在关闭请求之前,服务器和客户端能顺利进行信息传输.而不用像HTTP那样每一次都要告诉服务器这个请求者是谁(身份鉴别信息). 在HTT ...
- Cowboy 开源 WebSocket 网络库
Cowboy.WebSockets 是一个托管在 GitHub 上的基于 .NET/C# 实现的开源 WebSocket 网络库,其完整的实现了 RFC 6455 (The WebSocket Pro ...
- WebSocket的实现与应用
WebSocket的实现与应用 前言 说到websocket,就不得不提http协议的连接特点特点与交互模型. 首先,http协议的特点是无状态连接.即http的前一次连接与后一次连接是相互独立的. ...
- 深入理解 Web 协议 (三):HTTP 2
本篇将详细介绍 HTTP 2 协议的方方面面,知识点如下: HTTP 2 连接的建立 HTTP 2 中帧和流的关系 HTTP 2 中流量节省的奥秘:HPACK 算法 HTTP 2 协议中 Server ...
- Node.js的学习路线
http://www.admin10000.com/document/4624.html 顺便关注一下博客:http://blog.fens.me/series-nodejs/ php socket框 ...
随机推荐
- .NET Core开发日志——GraphQL
GraphQL是什么 GraphQL既是一种用于API的查询语言也是一种通过使用对应数据的类型系统,执行数据查询的服务端运行时.GraphQL没有局限于任何数据库或存储引擎,而是通过既有代码及数据获得 ...
- linux_grub resue模式恢复
//20190417 今天中午装linux的电脑崩了…… 一开始还以为是什么硬件问题,搞了半天,是更新的时候吧grub启动项弄坏了 行吧,没人教咱就上网搜,搞一下午搞出来了 ============= ...
- SQL语句之on子句过滤和where子句过滤区别
1.测试数据: SQL> select * from dept; DEPTNO DNAME LOC ------ -------------- ------------- ...
- X86-32位架构的CPU是不是内存只能到4G
不是的,可以通过分页机制扩展实现超过4G内存的支持. 什么是分页机制扩展? PAE. 什么是PAE? PAE如何实现的?
- SVN百度云服务器安装使用。
安装SVN客户端 此时,必须重启,否则经常出现用不了. 重启后,还是用不了的话,那么就重新安装系统. 网站地址: http://xiaomosheng.bceapp.com/ SVN代码服务器的地址: ...
- LINQ交集/并集/差集/去重
using System.Linq; List<string> ListA = new List<string>(); List<string> ListB = n ...
- 2019-04-15 Python中的面向对象学习总结
一.面向对象总结: (1)三要素:封装,继承,多态 详细介绍链接:https://www.jianshu.com/p/68a ...
- Ch07 包和引入 - 练习
1. 编写示例程序,展示为什么 package com.horstmann.impatient 不同于 package com package horstmann package impatien ...
- python 批量ping脚本不能用os.system
os.system(cmd)通过执行命令会得到返回值. ping通的情况下返回值为0. ping不通的情况: 1.请求超时,返回值1 2.无法访问目标主机,返回值为 0,和ping通返回值相同 所 ...
- 使用 notify.js 桌面提醒
//var iN = new iNotify({ // effect: 'flash', // interval: 500, // message: "有消息拉!", // aud ...