websocekt原理及实现过程
2017-03-27 19:29
411 查看
1.websocket协议:
可以将 WebSocket看成是一种类似TCP/IP的socket技术;此socket在Web应用中实现,并获得了和TCP/IP通信一样灵活方便的全双向通信功能。WebSocket协议由RFC 6455定义。协议分为两个部分: 握手阶段和数据通信阶段。
WebSocket为应用层协议,其定义在TCP/IP协议栈之上。
WebSocket连接服务器的URI以”ws”或者”wss”开头。ws开头的默认TCP端口为80,wss开头的默认端口为443。
Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。
2.websocket的优点:
1)通过第一次HTTP Request建立了连接之后,后续的数据交换都不用再重新发送HTTP Request,节因此它省了带宽资源;2) WebSocket的连接是双向通信的连接,在同一个TCP连接上,既可以发送,也可以接收;
3)具有多路复用的功能(multiplexing),也就是说几个不同的URI可以复用同一个WebSocket连接。
3.websocket的作用:
在说明白websocket的作用之前,还是先弄清楚轮询以及long poll的好,如此才能更好的对比出websocket的作用以及他的好处。a.轮询:
轮询呢,顾名思义就是每隔几一段时间去做一件事情,这里就是每隔一定的时间,客户端就向web服务器发一次请求,请求当前的新数据。轮询却是是一个合理的方案,但是有时候他的效率就不是很高,因为轮询就意为这要向服务器发起请求,要不断的建立新的连接,而这样做只是为了知道是否有新的数据,试想一下如果有成千上万的用户都这样轮询,时间一长服务器受得了吗?
是不是不太理解?O=O,,,,,没关系,简单的说,,,,
比如:你喜欢某个蛋糕店,于是在那里办了个会员卡,想着只要蛋糕出新你就去买,,于是就出现如下对话(前提,这个老板有健忘症,放下你的会员卡就忘记你是谁了):
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:没有。
,,,,,过了一天,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:没有,没有。
,,,,,又过了一天,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:没有。
,,,,,又过了一天,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:你咋这么烦,没有没有没有。
,,,,,又过了一天,你还是厚着脸皮去了,,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:给给给,拿走,烦死人
,,,,,于是你开开心心的走了,可是吃完后你又去了,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:没!有!
,,,,,过了一天,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?
老板(Response)检查了会员卡:没有。
,,,,,,于是你陷入了无限询问有没有新蛋糕中,,,,,,,
这就是轮询,,,想想,要是有很多个你这样的人,,那老板过几天是不是得进精神病院啊,,,,,^_^!
咱们来看看图:
b.long poll:
long poll 其实原理跟 轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。场景再现:
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?没有的话就算了,等有了给我打电话叫我罢。
老板(Response)检查了会员卡,记下你的电话,默默地不回话。
,,,,,于是你就一直等着,过了好几天,你的电话才响,,,,,,
老板(Response):给,给你新蛋糕。
,,,,,你很开心的取回蛋糕,很快吃完了,于是你又去了蛋糕店,,,,,
你(Request)将会员卡递给老板:老板,有没有出新蛋糕啊?没有的话就算了,等有了给我打电话叫我罢。
老板(Response)检查了会员卡,记下你的电话,默默地不回话。
,,,,,于是你就一直等着,过了好几天,你的电话才响,,,,,,
老板(Response):给,给你新蛋糕。
如此,你又陷入了无限的询问与等待中,,,,
这就是long poll 即为长轮询,O(*)O|||
看图看图:
c.websocket:
终于到主角了,,通过上面两个对话,我们可以看出,这两种方式都不是最好的,需要很多资源,也浪费了很多的带宽。
况且HTTP还是一个状态协议。
通俗的说就是,服务器因为每天要接待太多客户了,是个健忘鬼,你一离开,他就把你的东西全忘光了,把你的东西全丢掉了。你第二次还得再告诉服务器一遍。
所以在这种情况下出现了,Websocket出现了。他解决了HTTP的这几个难题。
首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。所以情景可以做如下修改:
你(Request):老板,我们用websocket联系罢,需要的服务:chat,Websocket协议版本:17(HTTP Request)
老板(Response)检查了会员卡:嗯,已升级为最新版。
你(Request):那,老板要是出了新蛋糕,记得告诉我哦。
老板(Response):好的,有的话就告诉你。
。。。。。于是你就回家敲代码去了。。。。。。
老板(Response):今天出了草莓蛋糕,你快来,,,
。。。。。你欢欢喜喜的取回蛋糕,继续敲代码。。。。。
老板(Response):今天有巧克力蛋糕哦
。。。。。你欢欢喜喜的取回蛋糕,继续敲代码。。。。。
老板(Response):………….
老板(Response):………….
就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你 )
客户端和服务器建立TCP连接之后,客户端发送握手请求,随后服务器发送握手响应即完成握手阶段,看图看图:
来来来,,对话看完了,咱们来总结一下:
这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。那么为什么他会解决服务器上消耗资源的问题呢?
其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。简单地说,我们有一个非常快速的 接线员(Nginx) ,他负责把问题转交给相应的 客服(Handler) 。
本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。
Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。
这样就可以解决客服处理速度过慢的问题了。
同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输 identity info (鉴别信息),来告诉服务端你是谁。
虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。
但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。
同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了。
4.websocket示例(客户端使用js):
var websocket = new WebSocket("ws://www.host.com/path"); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { onError(evt) }; } function onMessage(evt) { alert( evt.data); } function onError(evt) { alert( evt.data); } websocket.send("client to server");
a.创建一个WebSocket对象,传入一个URL值,以ws://或者wss://开头,原理和http://和https://相同。
b.使用WebSocket的四个事件:
onopen :会在建立连接后触发
onerror:会在出现问题时触发
onmessage:会在页面接受到消息时触发
onclose:会在连接关闭时触发
c.发送消息:在连接成功后,需要向服务器发送一条消息,发送消息要使用WebSocket对象的send()方法,改方法接受纯文本内容作为参数。
d.服务器在收到消息后就开始处理消息,此时触发onmessage事件
e.在网页认为有必要断开通信时,便调用close()方法
如:socket.close();
注意:一旦关闭socket,便不能再通信了,除非你再次建立websocket对象,再次重复以上的步骤。
5.关闭连接:
任何一端发送关闭帧给对方,即可关闭连接。关闭连接时通常都带有关闭连接的状态码(status code)。常见状态码的含义如下:1000 连接正常关闭
1001 端点离线,例如服务器down,或者浏览器已经离开此页面
1002 端点因为协议错误而中断连接
1003 端点因为受到不能接受的数据类型而中断连接
1004 目前保留其用法,会在将来给出定义
1005 保留, 用于提示应用未收到连接关闭的状态码
1006 端点异常关闭
1007 端点收到的数据帧类型不一致而导致连接关闭
1008 数据违例而关闭连接
1009 收到的消息数据太大而关闭连接
1010 客户端因为服务器未协商扩展而关闭
1011 服务器因为遭遇异常而关闭连接
1015 TLS握手失败关闭连接
相关文章推荐
- SDWebImage底层实现原理及内部实现过程
- SDWebImage底层实现原理及内部实现过程
- SDWebImage底层实现原理及内部实现过程
- Web上传文件的原理及实现
- 利用Java实现电信宽带上网的Web 认证---1. 原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- 利用反射原理和IExtenderProvider来实现WebControl与后台类的自动数据交换
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理
- VC点滴 之 WinMain(windows程序的运行原理以及VC++的实现过程)
- 也谈WEB打印(二):简单的分析一下IE的打印原理并实现简单的打印和预览
- (一)Java EE 5实现Web服务(Web Services)及多种客户端实例-原理