Nemo

Nemo 关注TA

路漫漫其修远兮,吾将上下而求索。

Nemo

Nemo

关注TA

路漫漫其修远兮,吾将上下而求索。

  •  普罗旺斯
  • 负责帅就完事了
  • 写了1,496,113字

该文章投稿至Nemo社区   Java  板块 复制链接


Websocket 探索

发布于 2017/12/19 11:03 2,229浏览 0回复 3,131

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也正是为了解决这个需要不断“打电话” 和 “挂电话” 的消耗资源的过程。

客户电话打通后,客服记录了客户需要的信息,并且约定有了客户需要的信息后,然后客服需要主动给客户返回数据(有点类似于程序里的回调),当然,除非客户主动告诉客服说他不需要这些信息了(断开连接)。



好吧,我也就随便写写,还没睡醒,可能有逻辑漏洞或者原理和真实的不一致等等,仅供参考。。。

本文标签
 {{tag}}
点了个评