1. 作用
Web Socket(套接字)的目标Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信。
2. 流程
在 JavaScript中创建 Web Socket 时,一个 HTTP 请求会发送到服务器以初始化连接。服务器响应后,连接使用 HTTP的 Upgrade 头部从 HTTP 协议切换到 Web Socket 协议。这意味着 Web Socket 不能通过标准 HTTP 服务器实现,而必须使用支持该协议的专有服务器。(Web Socket 得到了所有主流浏览器支持。)
因为 Web Socket使用了自定义协议,所以 URL方案(scheme)稍有变化:不能再使用 http://或 https://,而要使用 ws://和 wss://。前者是不安全的连接,后者是安全连接。
3. 优点和缺点
- 优点:客户端与服务器之间可以发送非常少的数据,不会对HTTP 造成任何负担。使用更小的数据包让 Web Socket 非常适合带宽和延迟问题比较明显的移动应用。
- 缺点:定义协议的时间比定义 JavaScript API 要长。
4. API
1. 创建
//传入提供连接的 URL
let socket = new WebSocket("ws://www.example.com/server.php");
注意,必须给 WebSocket 构造函数传入一个绝对 URL。同源策略不适用于 Web Socket,因此可以打开到任意站点的连接。至于是否与来自特定源的页面通信,则完全取决于服务器。(在握手阶段就可以确定请求来自哪里。)
2. readyState 和事件
readyState属性:
- WebSocket.OPENING(0):连接正在建立。
- WebSocket.OPEN(1):连接已经建立。
- WebSocket.CLOSING(2):连接正在关闭。
- WebSocket.CLOSE(3):连接已经关闭。
事件
| 事件 | 事件处理程序 | 描述 |
|---|---|---|
| open | Socket.onopen | 连接建立时触发 |
| message | Socket.onmessage | 客户端接收服务端数据时触发 |
| error | Socket.onerror | 通信发生错误时触发 |
| close | Socket.onclose | 连接关闭时触发 |
socket.onopne = function() {
console.log('已连接');
}
3. 方法
| 方法 | 描述 |
|---|---|
| Socket.send() | 使用连接发送数据 |
| Socket.close() | 关闭连接 |
任何时候都可以调用 close()方法关闭 Web Socket 连接:
socket.close();
调用 close()之后,readyState 立即变为 2(连接正在关闭),并会在关闭后变为 3(连接已经关闭)。
4. 发送和接收数据
打开 Web Socket 之后,可以通过连接发送和接收数据。要向服务器发送数据,使用 send()方法并传入一个字符串、ArrayBuffer 或 Blob,如下所示:
let socket = new WebSocket("ws://www.example.com/server.php");
let stringData = "Hello world!";
let arrayBufferData = Uint8Array.from(['f', 'o', 'o']);
let blobData = new Blob(['f', 'o', 'o']);
socket.send(stringData);
socket.send(arrayBufferData.buffer);
socket.send(blobData);
socket.send(stringData);
socket.send(arrayBufferData.buffer);
socket.send(blobData);
客户端收到服务器信息时触发message事件,如下所示:
socket.onmessage = function(event) {
let data = event.data;
//处理数据操作
}
event.data 返回的数据也可能是 ArrayBuffer 或 Blob。
这由 WebSocket 对象的 binaryType 属性决定,该属性可能是"blob"或"arraybuffer"。
5. 请求头
一个典型的Websocket握手请求如下:
客户端请求
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
服务器回应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/
- Connection 必须设置 Upgrade,表示客户端希望连接升级。
- Upgrade 字段必须设置 Websocket,表示希望升级到 Websocket 协议。
参考文章
JavaScript高级程序设计(四)