本文档介绍了 Deno 对 WebSocket 协议的实现,包括客户端 WebSocket 连接以及通过 HTTP 升级实现的服务器端 WebSocket 处理。此实现支持传统的 WebSocket API 和较新的 WebSocketStream API,并全面支持 HTTP/1.1 和 HTTP/2 协议。
有关 HTTP 服务器功能,请参阅Fetch 和 HTTP。有关通用网络原语,请参阅网络。
Deno 的 WebSocket 实现跨越多个层,从 JavaScript API 到基于 Rust 的协议处理。该系统同时支持客户端连接和服务器端 WebSocket 升级。
来源:ext/websocket/lib.rs903-935 ext/websocket/01_websocket.js126-274 ext/websocket/02_websocketstream.js93-285
客户端 WebSocket 实现从 JavaScript WebSocket 构造函数开始,一直到建立底层的网络连接。
来源:ext/websocket/01_websocket.js126-274 ext/websocket/lib.rs467-533
WebSocket 构造函数执行多个验证步骤
| 验证步骤 | 实现 | 错误类型 |
|---|---|---|
| URL Scheme | 只允许 ws: 和 wss: | SyntaxError |
| URL 片段 | WebSocket URL 不允许片段 | SyntaxError |
| 协议重复 | 不能多次提供相同的协议 | SyntaxError |
| 权限 | 需要网络访问权限 | PermissionCheckError |
来源:ext/websocket/01_websocket.js158-217
握手过程根据协议方案和 HTTP 版本而有所不同
来源:ext/websocket/lib.rs277-299 ext/websocket/lib.rs302-328 ext/websocket/lib.rs331-384
WebSocket 实现支持多种数据类型用于发送和接收消息
| 数据类型 | Send 方法 | Op 实现 | 接收类型 |
|---|---|---|---|
| 字符串 | send(string) | op_ws_send_text | MessageEvent,数据为 string |
| ArrayBuffer | send(arrayBuffer) | op_ws_send_binary_ab | MessageEvent,数据为 ArrayBuffer/Blob |
| ArrayBufferView | send(view) | op_ws_send_binary | MessageEvent,数据为 ArrayBuffer/Blob |
| Blob | send(blob) | 异步转换为二进制 | MessageEvent,数据为 ArrayBuffer/Blob |
来源:ext/websocket/01_websocket.js337-373 ext/websocket/lib.rs646-687
服务器端 WebSocket 支持通过升级机制与 Deno 的 HTTP 服务基础设施集成。
来源:ext/http/01_http.js360-383 ext/http/lib.rs202-224
升级过程涉及 HTTP 扩展处理的几个关键步骤
ServerWebSocket 资源来源:ext/http/websocket_upgrade.rs235-299
The ServerWebSocket 资源管理服务器端连接的生命周期
来源:ext/websocket/lib.rs556-601
The WebSocketStream API 使用 Streams API 提供了一种更现代、基于流的 WebSocket 通信方法。
来源:ext/websocket/02_websocketstream.js102-285
| 功能 | 传统 WebSocket | WebSocketStream |
|---|---|---|
| API 样式 | 基于事件 | 基于流 |
| 反压 | 手动缓冲 | 通过流自动处理 |
| 数据流 | 回调 (onmessage) | ReadableStream.read() |
| Send 方法 | send() 同步/异步 | WritableStream.write() |
| 错误处理 | 事件监听器 | Promise 拒绝 |
来源:ext/websocket/01_websocket.js337-373 ext/websocket/02_websocketstream.js210-249
Deno 的 WebSocket 实现支持 HTTP/1.1 和 HTTP/2 协议,并具有自动回退机制。
来源:ext/websocket/lib.rs310-328 ext/websocket/lib.rs331-384
消息处理遵循一致的模式,无论底层 HTTP 版本如何
| 消息类型 | Op Code | JavaScript 事件 | 数据处理 |
|---|---|---|---|
| 文本 | 0 | message,带 string | UTF-8 验证 |
| 二进制文件 | 1 | message,带 ArrayBuffer/Blob | 直接二进制数据 |
| Pong | 2 | 内部处理 | 心跳响应 |
| Close | >5 | close 事件 | 连接终止 |
| 错误 | 3 | error 事件 | 错误传播 |
来源:ext/websocket/01_websocket.js463-557 ext/websocket/lib.rs825-901
Deno 中的 WebSocket 连接与其他网络操作一样,受相同的权限模型约束。
来源:ext/websocket/lib.rs158-182 ext/websocket/01_websocket.js213-217
该权限系统会验证:
wss:// 连接的 TLS 证书验证