ArcherWong博客
首页
博客
websocket协议
作者:ArcherWong
分类:web
时间:2019-01-04 10:38:34
阅读:651
[TOC] # 1. websocket协议 WebSocket协议提供一个供TCP连接进行双向通讯的机制,基于TCP传输协议,并复用HTTP的握手通道。 # 2. 长连接,轮询,长轮询,websocket的前世今生 我们可能经常会听到长连接,轮询,长轮询,websocket这几个概念,并且可能对他们的区别有些模糊 ## 2.1 websocket与http的关系 他和http的协议就如同下面的关系,有共用的部分,但不是一个东西。Websocket其实是一个新协议,跟HTTP协议不同,为了兼容现有浏览器的握手规范,借用了HTTP的协议来完成一部分握手,所以他们在握手阶段是基本一样的。  ## 2.2 长连接 在我们的认识下,http协议中,Request = Response,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。 每一个请求开始后都会经历握手的过程,握手结束后开始传输数据,显然这样的效率不高,所有聪明的开发者们想到了,可不可以在一次握手结束后,发送多个请求,并接收多个请求,keep-alive应运而生。HTTP有1.1和1.0之说,http1.1一个比较重要的方面就是增加了keep-alive,HTTP1.1的连接默认使用持续连接。 ## 2.3 轮询 轮询 的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。 场景再现: 客户端:.有没有新信息(Request) 服务端:没有.(Response) 客户端:..有没有新信息(Request) 服务端:没有..(Response) 客户端:...有没有新信息(Request) 服务端:有消息,告诉你,今天要下雨...(Response) 客户端:...有没有新消息(Request) 服务端:没有..(Response) 。。。。。。 ---- loop 很明显这样的方式,轮询就会造成对网络和通信双方的资源的浪费,且非实时 ## 2.4 长轮询 长轮询其实原理跟轮询差不多,都是采用轮询的方式,不过采取的是阻塞模型,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。 场景再现 客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) 服务端:额。。 等待到有消息的时候。。来 给你(Response) 客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) 。。。。 ----loop 相比于轮询,这种方式网络带宽占用少了,但是本质上都体现了服务器的被动型,只有请求过来,才能回答,不能主动与客户端沟通。 ## 2.5 websocket 相对于http协议,websocket协议在握手阶段结束,建立起连接后,双方通讯会一直保持,并且客户端和服务端任何一方都可以主动向对方发送新消息,并且另一端通过监听onXXX事件可以收到这个信息。 # 3. websocket的详细介绍 它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。WebSocket 允许服务器端与客户端进行全双工(full-duplex)的通信。 其他特点包括: (1)建立在 TCP 协议之上,服务器端的实现比较容易。 (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。 (3)数据格式比较轻量,性能开销小,通信高效。 (4)可以发送文本,也可以发送二进制数据。 (5)没有同源限制,客户端可以与任意服务器通信,完全可以取代 Ajax。 (6)协议标识符是ws(如果加密,则为wss,对应 HTTPS 协议),服务器网址就是 URL。 WS协议有两部分组成:握手和数据传输。 ## 3.1 websocket握手阶段 这就是我们所了解的TCP三次握手,重温下这个经典的瞬间。。。  下面是我截取的一个websocket请求  通过上图可以看到和http的请求响应很像, 请求头中,这里需要注意几个域,有一个 HTTP 头是Upgrade。HTTP1.1 协议规定,Upgrade表示将通信协议从HTTP/1.1转向该字段指定的协议。Connection字段表示浏览器通知服务器,如果可以的话,就升级到 WebSocket 协议。Origin字段用于提供请求发出的域名,供服务器验证是否许可的范围内(服务器也可以不验证)。Sec-WebSocket-Key则是用于握手协议的密钥,是 Base64 编码的16字节随机字符串。 响应头中,服务器同样用Connection字段通知浏览器,需要改变协议。Sec-WebSocket-Accept字段是服务器在浏览器提供的Sec-WebSocket-Key字符串后面,添加“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”字符串,然后再取 SHA-1 的哈希值。浏览器将对这个值进行验证,以证明确实是目标服务器回应了 WebSocket 请求。 ## 3.2 数据传输 看一下客户端的简单实例 ``` var ws = new WebSocket('wss://echo.websocket.org'); ws.onopen = function(evt) { console.log('Connection open ...'); ws.send('Hello WebSockets!'); }; ws.onmessage = function(evt) { console.log('Received Message: ' + evt.data); ws.close(); }; ws.onclose = function(evt) { console.log('Connection closed.'); }; ``` 代码比较简单,也容易理解,就是几个回调函数。同样服务端也要实现监听事件,这样双方就可以通讯了。需要注意的是,websocket不仅可以发送text类型数据,还可以发送二进制数据,如果有需要,on message 的时候可以进行下判断。 # 参考资料 https://www.zhihu.com/question/20215561 http://javascript.ruanyifeng.com/htmlapi/websocket.html#toc0
标签:
上一篇:
http报文
下一篇:
会话管理方式
文章分类
css
elasticsearch
git
golang
guacamole
javascript
letsencrypt
linux
nginx
other
php
python
vue
web
阅读排行
letsencrypt证书-管理工具certbot
centos7.3配置guacamole
golang笔记---关联数组(map)
golang笔记---template模板语法
nginx笔记-proxy_cache缓存详解
友情链接
node文件
laravel-vue
ArcherWong的博客园