【演变】Ajax(AjAj)到WebSocket

时间:2023-03-08 17:23:23

提出问题:A  =>  服务器  =>  B           B端浏览器如何知道服务器有A发来的数据?

解决方案:

第1种:频繁轮询    间隔1秒B向服务器讨要数据,就算数据为空。【浪费服务器大量响应请求资源】

第2种:长轮询    服务器要发数据时才发,如果在服务器响应前,浏览器有新数据只能走并行请求(或者终止当前请求。)

    这里有个限制,一般来说规范【超时时间是60秒】。

    还有个限制,HTTP1.1版本浏览器只能发起两个连接到同一个主机名。(一般1个连接请求,另1个连接负责抓取图片资源。)

第3种:分块编码  用Transfer-Encoding:chunked代替Content-Length:lenN 【解决长轮询超时限制(大文件下载分块)但不能解决浏览器只能创建两个连接】

  初始化 创建一个接收服务器发送的事件监听,后续每个块都是事件触发XMLHttpRequest对象的onreadystatechange事件处理器调用。(连接需要刷新)

第4种:Applet 、Flash  在浏览器和服务器之间【单个连接模拟全双工通信】,本质创建了TCP插头,绕过HTTP协议超时和并发连接限制,以及Ajax安全限制必须要同一个完全限定域名。

  插件本身没有安全协议,缓慢占内存...随着移动互联网,渐渐被取代。

【WebSocket协议】原生的TCP插头。80(ws)  443(wss) ,几乎所有防火墙都不阻塞WebSocket连接。

【Http1.1版本升级特性的利用】最早在请求中包含Connection:Upgrade,常被用来从HTTP升级到HTTPS,容易收到中间人攻击所以被HTTPS URI替代。

【使用HTTP升级特性】在升级握手完成之后,不再使用HTTP连接,这时候可以使用持久的、全双工TCP插头连接。

【浏览器厂商规范】协议:ws[s]   头部:Connection:Upgrade Upgrade:websocket

    其实HTTP请求不含 ws[s]。只是告诉浏览器要不要SSL/TLS加密。

【初始化】A => 服务器        服务区 => A  101交换协议

【初始化后心跳消息】ping pong

请求

GET /webSocketEndpoint HTTP/1.1

Host:www.example.org

Connection:Upgrade

Origin:http://example.com

Sec-WebSocket-Key:x3JJHMbDL1EzLkh9GBhxDw==   //base64编码  浏览器生成

Sec-WebSocket-Version:13

Sec-WebSocket-Protocol:game   //聊天、游戏、股票

响应

HTTP/1.1 101 状态码描述

Server:Apache 2.4

Connection:Upgrade

Upgrade:webSocket

Sec-WebSocket-Accept:x3JJHMbDL1EzLkh9GBhxDw==   //base64编码  浏览器生成

Sec-WebSocket-Protocol:game   //聊天、游戏、股票

TCP插头接入,websocket连接开始,最大的障碍是HTTP代理,最可靠的方式是是用HTTPS版本wss。