websocket工作原理,websocket 详解
http://blog..net/frank_good/article/details/50856585
偶然在知乎上看到一个回复,瞬间觉得之前看的那么多资料都不如这个回复,让我对websocket有了深刻的认识。所以去我的博客分享一下吧。我更喜欢看这类博客。读起来很轻松,不枯燥,也没有布道者之战,只是为了分享。废话那么多,给你最后一个赞~
1.websocket和http
WebSocket是HTML5的一个产品(协议),也就是说HTTP协议没变,或者说没关系,但是HTTP不支持持久连接(长连接,循环连接不算)。
首先,HTTP有1.1和1.0,即所谓的keep-alive,将多个HTTP请求合二为一。不过Websocket其实是一个新的协议,基本上和HTTP协议没什么关系,只是为了兼容现有浏览器的握手规范。也就是说它是对HTTP协议的补充,从这样一个图就可以理解。
有交集,但不是全部。
另外,Html5指的是一系列新的API,或者说新的规范和技术。Http协议本身只有1.0和1.1,和Html本身没有直接关系。一般来说,可以用HTTP协议传输非Html数据,就是这样=。=
简单来说就是层次不同。
二、Websocket是一种什么样的协议,具体有什么优势?
首先,Websocket是一个持久性协议,相对于非持久性协议HTTP。我们举个简单的例子,用目前广泛使用的PHP生命周期来解释。
HTTP的生命周期是由请求定义的,即一个请求和一个响应,所以在HTTP1.0中,这个HTTP请求就结束了。
在HTTP1.1中,它被改进为具有keep-alive,即在一个HTTP连接中,可以发送多个请求并接收多个响应。但是请记住Request=Response,在HTTP中总是这样,也就是说一个请求只能有一个响应。而且这种反应是被动的,不能主动发起。
蔻驰,你BB这么多,跟Websocket有什么关系?_(:“)_嗯,我正要说Websocket。
首先,Websocket是基于HTTP协议的,或者说是借用HTTP协议来完成一些握手。
首先,我们来看一个典型的Websocket握手(借用维基百科。)
获取/聊天HTTP/1.1
主持人:server.example.com
升级:websocket
连接:升级
sec-web socket-Key:x3jjhmbdl 1 ezlkh 9 gbhxdw==
sec-web socket-协议:聊天,超级聊天
sec-web socket-版本:13
产地:http://example.com
熟悉HTTP的童鞋可能已经发现,这个握手请求中类似HTTP协议的东西还多了几个。我顺便解释一下功能。
升级:websocket
连接:升级
这是Websocket的核心。告诉Apache、Nginx等服务器:注意,我发起了Websocket协议。请帮我找相应的助手快速处理~不是那么老套的HTTP。
sec-web socket-Key:x3jjhmbdl 1 ezlkh 9 gbhxdw==
sec-web socket-协议:聊天,超级聊天
sec-web socket-版本:13
首先Sec-Websocket-Key是Base64 encode的一个值,由浏览器随机生成。告诉服务器:泥炭,别糊弄窝。我想验证一下Tony是不是真的是WebSocket助手。
然后,Sec_WebSocket-Protocol是一个自定义字符串,用来区分同一URL下不同服务所需的协议。简单理解:今晚我要去服A,别搞错了~
最后,Sec-Websocket-Version告诉服务器使用的是哪个Websocket草案(协议版本)。当初Websocket协议还在草案阶段,有各种奇怪的协议,有很多奇怪的东西,比如Firefox和Chrome用不同的版本。起初,太多的WebSocket协议是一个大问题。不过现在好了,解决了~大家都用的东西~脱水:服务员,我要一个13岁的哦_
然后服务器会返回如下,表示请求已经收到,Websocket已经成功建立!
HTTP/1.1 101交换协议
升级:websocket
连接:升级
sec-web socket-Accept:hsmrc 0 smlyukagmm 5 oppg 2 hag wk=
sec-web socket-协议:聊天
这里是HTTP最后负责的区域。告诉客户我已经成功切换协议了~
升级:websocket
连接:升级
它仍然是固定的,告诉客户端Websocket协议即将升级,而不是mozillasocket、lurnarsocket或shitsocket。
那么,Sec-WebSocket-Accept就是已经被服务器确认并加密的Sec-WebSocket-Key。服务器:好,好,我知道了。我给你看我的身份证证明一下。
后来Sec-WebSocket-Protocol就是最后要用的协议。
至此,HTTP已经完成了所有的工作,接下来就完全按照Websocket协议进行了。具体协议这里就不细说了。
3354————,技术分析部分讲完了,33543333333334
你BBB了这么久,Websocket到底有什么用?http长轮询或ajax轮询可以实现实时信息传输。
好了,小伙子,我们来谈谈Websocket的使用。来,我给你一些胡(苏)罗(丹)布(红)
第三,Websocket的作用
在讲Websocket之前,我先讲一下长轮询和ajax轮询的原理。
Ajax轮询
ajax轮询的原理很简单,浏览器每隔几秒就发送一个请求,询问服务器是否有新的信息。
客户:啦啦啦,有没有新的信息(请求)
服务器:你这么烦,没有。(回应)
客户:啦啦啦,有什么新消息(请求)吗?
服务员:好的,好的,给你。(回应)
客户:啦啦啦,有什么新消息(请求)吗?
服务器:没有。没有。否(响应)——循环
长轮询
其实长轮询的原理和ajax轮询类似,都是采用轮询的方式,只是采用的是阻塞模式(一直打,没收到就别挂)。也就是说,客户端发起连接后,如果没有消息,就永远不会向客户端返回响应。直到有消息才返回。返回后,客户端再次建立连接,如此循环往复。
场景再现:
客户:啦啦啦,你有什么新消息吗?如果没有,请等到你有了再还给我(要求)
服务器:金额。等待消息。给你(回应)
客户:啦啦啦,有什么新消息吗?如果没有,就等你有了,再还给我(请求)-循环
从上面可以看出,其实这两种方法都是不断建立HTTP连接,然后等待服务器处理,这可以体现HTTP协议的另一个特点,被动性。
什么是被动?实际上,服务器无法主动联系客户端,只有客户端才能发起。
简单来说,服务器就是个懒冰箱(是个梗)(不会,不能主动发起连接),但是老板有命令,如果有客户来了,不管多累都要好好接待。
之后,让我们来谈谈上述缺陷(原谅我说了这么多废话OAQ)
从上面很容易看出来。无论如何,以上两种都是非常耗费资源的。
Ajax轮询要求服务器具有快速的处理速度和资源。(速度)长轮询需要有高并发,也就是同时接待客户的能力。(网站大小)
因此,ajax轮询和长轮询都可能发生。
客户:啦啦啦啦,有新消息吗?
服务器:月线忙,请稍后再试(503服务器不可用)
客户端:好吧,啦啦啦,有新消息吗?
服务器:月线忙,请稍后再试(503服务器不可用)
客户端:然后服务器端忙的要死:冰箱,我要更多的冰箱!更多。更多。我错了。这又是梗。)
无论如何,我们来谈谈Websocket。
从上面的例子我们可以看出,这两种方法都不是最好的,都需要大量的资源。
一个需要更快的速度,一个需要更多的‘电话’。两者都会导致对‘电话’的需求越来越高。
哦,对了,我忘了说HTTP还是有状态协议。
通俗地说,服务器就是一个健忘鬼,因为它每天接收的客户端太多了。你一挂电话,他就把你的东西全忘了,把你的东西全扔了。第二次你得再告诉服务器一次。
所以在这种情况下,Websocket出现了。他解决了HTTP的这些问题。首先是被动性,当服务器完成协议升级(HTTP- Websocket)时,服务器可以主动向客户端推送信息。所以上面的场景可以修改如下。
客户端:啦啦啦啦,我想建立Websocket协议,需要的服务:聊天,Websocket协议版本:17(HTTP请求)
服务器:好的,确认,已经升级到Websocket协议(HTTP协议切换)。
客户:有信息请推给我。
服务器:好的,我有时候会告诉你。
服务器:巴拉巴拉巴拉
服务器:巴拉巴拉巴拉
服务器:哈哈哈哈哈哈哈哈哈
服务器:笑死我了。哈哈哈哈哈哈哈哈。
变成了这样,只需要一个HTTP请求就可以实现源源不断的信息传输。(在编程中,这种设计叫回调,就是当你有信息的时候,请通知我,而不是每次都傻傻的问你。)
该协议解决了同步延迟和消耗大量资源的问题。那么他为什么要解决服务器上的资源消耗问题呢?
其实我们用的程序要经过两层代理,也就是HTTP协议由Nginx等服务器解析,然后传输到相应的Handler(PHP等。)进行处理。简单来说,我们有一个非常快的接线员(Nginx),负责把问题转给相应的客服(处理员)。
运营商自己的速度基本够用,但是每次卡在客服(处理员)那里,客服总是处理的太慢。导致客户服务不足。Websocket解决了这样一个问题。建立后,它可以直接与运营商建立永久连接。有信息的时候,客服会想办法通知运营商,然后运营商统一转给客户。
这样就解决了客服处理速度慢的问题。
同时,在传统的方式下,需要不断地建立和关闭HTTP协议。因为HTTP是非状态的,所以每次都要重新传输身份信息,告诉服务器你是谁。
虽然接线员速度很快,但是每次都要听这样一堆,效率就会降低。同时,他还要不断地将这些信息传递给客服,不仅浪费了客服的处理时间,也耗费了太多的网络传输流量/时间。
而Websocket只需要一次HTTP握手,所以整个通信过程都是在一个连接/状态下建立的,避免了HTTP的无状态。服务器会一直知道你的信息,直到你关闭请求,这样就解决了运营商要反复分析HTTP协议,检查身份信息的信息的问题。
同时客户端会主动询问,有空就转化为服务器(push)发送信息(当然客户端会等待主动发送信息。),没有资料的时候交给运营商(Nginx),这样就没必要占用慢客服(Handler)了。
——————
至于如何在不支持Websocket的客户端上使用Websocket。答案是:不会。
但是类似的效果可以通过上面提到的长轮询和ajax轮询来模拟。