1.
WebSocket协议,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式 对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应用。在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。
轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。明显地,这种方法会导致过多不必要的请求,浪费流量和服务器资源。
Comet技术又可以分为长轮询和流技术。长轮询改进了上述的轮询技术,减小了无用的请求。它会为某些数据设定过期时间,当数据过期后才会向服务端发送请求;这种机制适合数据的改动不是特别频繁的情况。流技术通常是指客户端使用一个隐藏的窗口与服务端建立一个HTTP长连接,服务端会不断更新连接状态以保持HTTP长连接存活;这样的话,服务端就可以通过这条长连接主动将数据发送给客户端;流技术在大并发环境下,可能会考验到服务端的性能。
这两种技术都是基于请求-应答模式,都不算是真正意义上的实时技术;它们的每一次请求、应答,都浪费了一定流量在相同的头部信息上,并且开发复杂度也较大。
伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具了C/S模式的实时通信能力。WebSocket的工作流程是这样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询和Comet技术小了很多。
2.
WebSocket 只需要建立一次连接,就可以一直保持连接状态
在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。
实现原理
浏览器发出webSocket的连线请求,服务器发出响应,这个过程称为握手,握手的过程只需要一次,就可以实现持久连接。
握手与连接
浏览器发出连线请求,通过get可以表明此次连接的建立是以HTTP协议为基础的,返回101状态码。
如果不是101状态码,表示握手升级的过程失败了
101是Switching Protocols,表示服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送这个响应后的空档,将http升级到webSocket。
其中Upgrade和Connection字段告诉服务端,发起的是webSocket协议
Sec-WebSocket-Key是浏览器经过Base64加密后的密钥,用来和response里面的Sec-WebSocket-Accept进行比对验证
Sec-WebSocket-Version是当前的协议版本
Sec-WebSocket-Extensions是对WebSocket的协议扩展
服务器接到浏览器的连线请求返回结果如下:
Upgrade和Connection来告诉浏览器,服务已经是基于webSocket协议的了,让浏览器也遵循这个协议
Sec-WebSocket-Accept是服务端确认后并加密后的Sec-WebSocket-Accept
至此,webSocket连接成功,接下来就是webSocket的协议了。
3.
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协议的握手请求中,多了几个东西
这个就是Websocket的核心了,告诉Apache、Nginx等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP
Sec-WebSocket-Key是一个Base64 encode的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理
Sec_WebSocket-Protocol是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~
Sec-WebSocket-Version是告诉服务器所使用的Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 脱水:服务员,我要的是13岁的噢→_→
服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦!
这里开始就是HTTP最后负责的区域了,告诉客户,我已经成功切换协议啦~
依然是固定的,告诉客户端即将升级的是Websocket协议,而不是mozillasocket,lurnarsocket或者shitsocket。
然后,Sec-WebSocket-Accept这个则是经过服务器确认,并且加密过后的Sec-WebSocket-Key。服务器:好啦好啦,知道啦,给你看我的ID CARD来证明行了吧。。
Sec-WebSocket-Protocol则是表示最终使用的协议
至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了。
当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)
4.websocket协议
简单来说,WebSocket是一种协议,与HTTP协议一样位于应用层,都是TCP/IP协议的子集。HTTP协议是单向通信协议,只有客户端发起HTTP请求,服务端才会返回数据。而WebSocket协议是双向通信协议,在建立连接之后,客户端和服务器都可以主动向对方发送或接受数据。WebSocket协议建立的前提需要借助HTTP协议,建立连接之后,持久连接的双向通信就与HTTP协议无关了。
WebSocket协议的目标是在一个独立的持久连接上提供全双工双向通信。客户端和服务器可以向对方主动发送和接受数据。在JS中创建WebSocket后,会有一个HTTP请求发向浏览器以发起请求。在取得服务器响应后,建立的连接会使用HTTP升级将HTTP协议转换为WebSocket协议。也就是说,使用标准的HTTP协议无法实现WebSocket,只有支持那些协议的专门浏览器才能正常工作。
由于WebScoket使用了自定义协议,所以URL与HTTP协议略有不同。未加密的连接为ws://,而不是http://。加密的连接为wss://,而不是https://。
Connection:Connection必须设置为Upgrade,表示客户端希望连接升级
Upgrade:Upgrade必须设置为WebSocket,表示在取得服务器响应之后,使用HTTP升级将HTTP协议转换(升级)为WebSocket协议。
Sec-WebSocket-key:随机字符串,用于验证协议是否为WebSocket协议而非HTTP协议
Sec-WebSocket-Version:表示使用WebSocket的哪一个版本。
Sec-WebSocket-Accept:根据Sec-WebSocket-Accept和特殊字符串计算。验证协议是否为WebSocket协议。
Sec-WebSocket-Location:与Host字段对应,表示请求WebSocket协议的地址。
HTTP/1.1 101 Switching Protocols:101状态码表示升级协议,在返回101状态码后,HTTP协议完成工作,转换为WebSocket协议。此时就可以进行全双工双向通信了。
一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端中断连接前,不需要客户端和服务端重新发起连接请求。
WebSocket的原理与机制
WebSocket协议分为两部分:握手和数据传输