diff --git "a/source/_posts/WebSocket\357\274\2101\357\274\211\357\274\232 \346\234\215\345\212\241\347\253\257\342\200\234\345\256\236\346\227\266\346\216\250\351\200\201\342\200\235\347\232\204\346\274\224\345\217\230.md" "b/source/_posts/WebSocket\357\274\2101\357\274\211\357\274\232 \346\234\215\345\212\241\347\253\257\342\200\234\345\256\236\346\227\266\346\216\250\351\200\201\342\200\235\347\232\204\346\274\224\345\217\230.md" new file mode 100644 index 0000000..8208acc --- /dev/null +++ "b/source/_posts/WebSocket\357\274\2101\357\274\211\357\274\232 \346\234\215\345\212\241\347\253\257\342\200\234\345\256\236\346\227\266\346\216\250\351\200\201\342\200\235\347\232\204\346\274\224\345\217\230.md" @@ -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. 签个双向合同吧,你有数据随时给我,我有数据随时给你 + +> 这个演变过程,看着很像双方地位从不平等到平等的过程。 + +*** + +### 对比 + +> 总结不太全,欢迎补充 + +| 方式 | 类型 | 技术实现 | 优点 | 缺点 | +| --------------------------------------- | --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 轮询
Polling | client→server | 客户端循环请求 | 1、简单
2、很容易理解
3、实现无额外技术成本
4、 支持跨域 | 1、浪费带宽和服务器资源
2、 一次请求信息大半是无用(完整http头信息)
3、 有延迟
4、大部分无效请求 | +| 长轮询
Long-Polling | client→server | 服务器hold住请求,一直到有数据或者超时才返回,减少重复请求次数 | 1、简单
2、不会频繁发请求
3、节省流量
4、延迟低 | 1、服务器hold,会消耗资源
2、维护多个线程
3、很容易占满TCP连接数 | +| 长连接:iframe/htmlfile | client→server | 在页面里嵌入一个隐蔵iframe/htmlfile,将这个 iframe 的 src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。 | 1、数据实时送达
2、不发无用请求,一次链接,多次“推送” | 1、服务器增加开销
2、无法准确知道连接状态
3、IE、FF 一直会处于loading状态 | +| 长连接:multi-part | client→server | 采用xhr请求,服务器端就能源源不断地往客户端输入数据。 | 1、数据实时送达
2、不发无用请求,一次链接,多次“推送” | 1、 并非所有的浏览器都支持 multi-part 标志 | +| Flash Socket | server→client | 使用了 Socket 的 Flash | 1、真·实时推送 | 1、必须安装Flash插件
2、非http协议,无法自动穿越防火墙 | +| SSE(Server Sent Events)服务器发送事件 | server→client | SSE【!IE】:new EventSource() | 1、服务端主动
2、数据流
3、支持断线重连 | 1、只是长连接
2、还是单向
3、IE不支持 | +| WebSocket | server ⇌ client | new WebSocket() | 1、双向协议
2、可发送二进制文件 | 1、浏览器支持程度不一致
2、不支持断开重连 | + +未完待续。。。 + +以上 + +by ReAlign \ No newline at end of file