-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2a60629
commit a9345ac
Showing
1 changed file
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# WebSocket(1): 服务端“实时推送”的演变 | ||
|
||
> 任何事物的演变,都是为了解决无法满足的需求,或者更好地满足需求。 ——沃·滋基·索德 | ||
### 引子 | ||
|
||
**一个都能看懂的日常:** | ||
|
||
1. (僵硬、重复、无聊...的)日常:画页面、发请求拿数据、写逻辑处理数据、发请求更新数据、... | ||
2. 突然有一天: | ||
* “这个请求你不一定能拿到数据,多发几次拿数据的请求吧,拿到数据算” | ||
* “为啥不一定能拿到数据?” | ||
* “处理数据很慢,我也不知道啥时候处理完” | ||
* “好吧,那我循环发请求吧” | ||
3. 然后,(僵硬、重复、无聊...的)日常各自码代码 | ||
4. 突然,(内心深处挣扎了一下)循环发请求太 low,想着怎么高大上一些 | ||
5. 然后,** 了一下,发现实现这个需求有好几种方式,然后就凌乱了... | ||
* 轮询 | ||
* 长轮询 | ||
* 长连接 Streaming | ||
* iframe | ||
* htmlfile | ||
* Flash Socket | ||
* 服务端发送事件 SSE | ||
* WebSocket | ||
|
||
* 我该怎么办??? | ||
|
||
### 演变过程 | ||
|
||
> 1、一趟一趟跑 | ||
#### 轮询(Polling) | ||
|
||
C:有数据了没?(第 1 趟) | ||
S:没 | ||
C:有数据了没?(第 2 趟) | ||
S:没 | ||
... | ||
C:(喘气.jpg)有数据了没?(第 n 趟) | ||
S:(黑脸.jpg)没~ | ||
... | ||
C:(生无可恋.jpg)有数据了没?(第 n+m 趟) | ||
S:有了,给你给你 | ||
|
||
![Polling](https://haitao.nos.netease.com/9416731d-e770-476a-a637-e1024ba8a779_1466_1566.png) | ||
|
||
*** | ||
|
||
> 2、跑过去等一会儿,万一拿到了呢,少跑一趟是一趟 | ||
#### 长轮询(Long-Polling) | ||
|
||
C:有数据了没?(第 1 趟) | ||
S:没 | ||
C:我等会吧,你快点 | ||
S:好 | ||
... | ||
S:我们要打烊了,你先走吧,明天再来 | ||
C:(MMP.jpg)好吧 | ||
... | ||
C:有数据了没?(第 n 趟) | ||
S:有了,给你给你 | ||
|
||
![Long-Polling](https://haitao.nos.netease.com/4b5584a3-45eb-4fa8-8807-da220166483a_1490_1630.png) | ||
|
||
*** | ||
|
||
> 3、跑过去预定,天黑前,还有新数据的话,让伙计送过来吧 | ||
#### 长连接Streaming / 服务端发送事件EventSource | ||
|
||
> 长连接Streaming:iframe/htmlfile/Flash Socket | ||
> | ||
> 服务端发送事件EventSource:SSE(Server Send Events) | ||
C:我预定下今天的数据。有数据没? | ||
S:没 | ||
C:好,天黑前,有新数据,让伙计送过来吧 | ||
S:(不情愿.jpg)行吧 | ||
... | ||
S:有b的数据了,伙计,送过去 | ||
... | ||
S:有c的数据了,伙计,噢,下班了呀。天都黑了,算了吧,等他再来吧 | ||
|
||
![](https://haitao.nos.netease.com/cde8e718-d3a6-4322-8bc7-26b8f9f8aa71_1408_1632.png) | ||
|
||
*** | ||
|
||
> 4、签个双向合同吧,你有数据随时给我,我有数据随时给你 | ||
#### WebSocket | ||
|
||
C:我们的合同执行吧,麻烦有数据的时候,推记得给我噢。。 | ||
S:ok | ||
S:我这有数据给你 | ||
C:👌,我这也有数据给你 | ||
S:👌,给你 | ||
... | ||
|
||
![WebSocket](https://haitao.nos.netease.com/0a97058b-50e7-4cc6-935d-9fab045bd8bb_1290_1562.png) | ||
|
||
*** | ||
|
||
1. 一趟一趟跑 | ||
2. 跑过去等一会儿,万一拿到了呢,少跑一趟是一趟 | ||
3. 跑过去预定,天黑前,还有新数据的话,让伙计送过来吧 | ||
4. 签个双向合同吧,你有数据随时给我,我有数据随时给你 | ||
|
||
> 这个演变过程,看着很像双方地位从不平等到平等的过程。 | ||
*** | ||
|
||
### 对比 | ||
|
||
> 总结不太全,欢迎补充 | ||
| 方式 | 类型 | 技术实现 | 优点 | 缺点 | | ||
| --------------------------------------- | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | ||
| 轮询<br>Polling | client→server | 客户端循环请求 | 1、简单<br />2、很容易理解<br />3、实现无额外技术成本<br />4、 支持跨域 | 1、浪费带宽和服务器资源<br />2、 一次请求信息大半是无用(完整http头信息)<br />3、 有延迟<br />4、大部分无效请求 | | ||
| 长轮询<br>Long-Polling | client→server | 服务器hold住请求,一直到有数据或者超时才返回,减少重复请求次数 | 1、简单<br />2、不会频繁发请求<br />3、节省流量<br />4、延迟低 | 1、服务器hold,会消耗资源<br />2、维护多个线程<br />3、很容易占满TCP连接数 | | ||
| 长连接:iframe/htmlfile | client→server | 在页面里嵌入一个隐蔵iframe/htmlfile,将这个 iframe 的 src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。 | 1、数据实时送达<br />2、不发无用请求,一次链接,多次“推送” | 1、服务器增加开销<br />2、无法准确知道连接状态<br />3、IE、FF 一直会处于loading状态 | | ||
| 长连接:multi-part | client→server | 采用xhr请求,服务器端就能源源不断地往客户端输入数据。 | 1、数据实时送达<br />2、不发无用请求,一次链接,多次“推送” | 1、 并非所有的浏览器都支持 multi-part 标志 | | ||
| Flash Socket | server→client | 使用了 Socket 的 Flash | 1、真·实时推送 | 1、必须安装Flash插件<br />2、非http协议,无法自动穿越防火墙 | | ||
| SSE(Server Sent Events)服务器发送事件 | server→client | SSE【!IE】:new EventSource() | 1、服务端主动<br />2、数据流<br />3、支持断线重连 | 1、只是长连接<br />2、还是单向<br />3、IE不支持 | | ||
| WebSocket | server ⇌ client | new WebSocket() | 1、双向协议<br />2、可发送二进制文件 | 1、浏览器支持程度不一致<br />2、不支持断开重连 | | ||
|
||
未完待续。。。 | ||
|
||
以上 | ||
|
||
by ReAlign |