1、说到websocket,就不得不提一下他的前辈http了:
熟悉http的童鞋应该都知道,HTTP是不支持持久连接的(长连接,循环连接的不算)。
html5是指一系列新的api,Http协议本身只有1.0和1.1(其实http跟html好像也没啥关系哈),html5其实相当于是旧的html api的一种补充。
而WebSocket是HTML5出的东西。
HTTP 有所谓的keep-alive之说 ,也就是把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已。
也就是说Websocket 出现后,其实HTTP协议没有变化。
Websocket跟Http的关系非得有一种描述的话,大概是:有交集,但是并不是全部。
2、Websocket与http的关系/区别?
HTTP:
如果非得要举个栗子来说明的话,大概需要说说http中的request 和 response。
在http中,一个http连接的生命周期其实也就是request 和对应的response,并且一个request 只能有一个response。所以一个http发了一个请求,并且得到服务器返回的结果,那么这个http的生命周期也就走完了。
另外我觉得应该顺带提一下:在http1.0 中,一个http连接只能有一个request和一个response,而在http1.1中加入了keep-alive这个玩意,所以http1.1中一个http连接中,可以包含多个request和response。但是,不管是1.0 还是 1.1,一个request只能有一个response,并且response是被动的,不能主动发起。
顺便贴一个http的握手请求的内容:
POST /test/http?a=1 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0, no-cache
Pragma: no-cache
Content-Length: 8
b=aaaaaa
Websocket:
首先,Websocket是基于http的。它借助了http的协议来与服务端完成部分握手,众知在一次http请求中,客户端与服务端需要到3次握手才能与彼此建立通信通道,这里就不多提及http握手协议了。
然后我们可以看一下Websocket的握手请求的内容:
GET /websocket HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: websocket
Sec-WebSocket-Version: 13
Origin: http://localhost
可以看到,Websocket的握手请求中,多了不少在http请求中没有见过的内容:
Upgrade: websocket
Connection: Upgrade
这两个内容表明这是一个websocket请求,而不是http。
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: websocket
Sec-WebSocket-Version: 13
这三个则分别代表了验证对方的随机密钥,本次连接的目标地址,websocket协议版本。
但是不管怎么说,可以看到请求内容的第一行:
GET /websocket HTTP/1.1
表明了它是使用http1.1的协议来与目标建立的握手协议。
建立完连接后,服务端会返回如下数据:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: websocket
也就是告诉客户端,服务端已经将请求切换到websocket协议了。从这之后,websocket跟http的交集部分也算是完全结束了,接下来所有的动作都将按照websocket的协议约定来进行。
3、长轮询 、 普通轮询 ?
3、1 普通轮询:就是客户端不断唠唠叨叨的跟服务端交流,然后服务端每次被客户端问话的时候,还必须给客户端回应。
举个栗子:
客户给客服打通了电话。
客户:有没有我的信息?(我发了一个Request)
客服:暂时没有哦。(给你Response)
电话挂断。
(15s later)
客户给客服打通了电话。
客户:有没有我的信息?
客服:暂时没有哦。
电话挂断。
(15s later)
客户给客服打通了电话。
客户:有没有我的信息?(我发了一个Request)
客服:暂时没有哦。(给你Response)
电话挂断。
(15s later)
客户给客服打通了电话。
客户:有没有我的信息?
客服:好的,你有一个新信息哦。
电话挂断。
。。。。。。
3、2 长轮询:其实跟普通轮询原理差不多。客户端与服务端,他们也是在一直处于一个“轮询”的过程的。不过“轮询”一次,服务端不会立即返回数据给客户端,而是等到找到了客户端请求的数据才返回,完成一次“轮询”后,他们会自主的建立起新的连接。
举个栗子:
客户给客服打通了电话。
客户:如果有信息的时候再告诉我。(我发了一个Request)
(然后没挂电话,等了15分钟)
客服:那客户,你有数据。(给你Response)
电话挂断。
客户给客服打通了电话。
客户:如果有信息的时候再告诉我。(我发了一个Request)(然后没挂电话,等了15分钟)
客服:那客户,你有数据。(给你Response)
电话挂断。
。。。
4、Websocket
其实可以看出,轮询跟长轮询,其实都有一个弊端。就是需要不断的“打电话”和“挂电话”。“打电话” 和 “挂电话”其实都需要消耗更多的资源。
还有一点就是,http中其实是没有状态的。也就是http不知道本次请求数据的客户端跟上一个客户端是不是同一个等等。
所以后来出现的Websocket也正是为了解决这个需要不断“打电话” 和 “挂电话” 的消耗资源的过程。
客户电话打通后,客服记录了客户需要的信息,并且约定有了客户需要的信息后,然后客服需要主动给客户返回数据(有点类似于程序里的回调),当然,除非客户主动告诉客服说他不需要这些信息了(断开连接)。
好吧,我也就随便写写,还没睡醒,可能有逻辑漏洞或者原理和真实的不一致等等,仅供参考。。。