Skip to main content
Bun.serve() 支持服务器端 WebSockets,具备实时压缩、TLS 支持以及 Bun 原生的发布-订阅 API。
⚡️ 吞吐量提升 7 倍Bun 的 WebSockets 速度非常快。以 Linux x64 上的简单聊天室为例,Bun 每秒能处理的请求数是 Node.js + "ws" 的 7 倍。Bun 内部的 WebSocket 实现基于 uWebSockets

启动 WebSocket 服务器

以下服务器使用 Bun.serve 构建,并在 fetch 处理程序中将每个传入请求升级为 WebSocket 连接。套接字处理程序在 websocket 参数中声明。
server.ts
Bun 支持以下 WebSocket 事件处理程序:
server.ts
在 Bun 中,处理函数只需为服务器声明一次,而不是为每个套接字重复声明。你可以将单个 WebSocketHandler 对象传递给 Bun.serve(),其中包含用于处理 openmessageclosedrainerror 的方法。这与客户端的 WebSocket 类不同,后者继承自 EventTargetonmessageonopenonclose)。客户端通常只会打开少量套接字连接,因此基于事件的 API 在客户端很适用。但服务器端往往会打开 大量 连接,这意味着:
  • 为每个连接添加/移除事件监听器所花费的时间会累积起来
  • 为每个连接存储回调函数引用会占用额外内存
  • 通常,人们会为每个连接创建新函数,这同样意味着更多的内存开销
在所有连接之间重复使用同一个处理程序对象,可以避免这两项开销。
每个处理程序的第一个参数都是负责处理该事件的 ServerWebSocket 实例。ServerWebSocket 类是一个快速的、原生 Bun 实现的 WebSocket,并提供了一些额外功能。
server.ts

发送消息

每个 ServerWebSocket 实例都有 .send() 方法用于向客户端发送消息,支持多种输入类型。
server.ts

头信息

升级成功后,Bun 会根据规范发送 101 Switching Protocols 响应。要为此 Response 附加额外的 headers,请将它们传递给 server.upgrade()
server.ts

上下文数据

.upgrade() 调用中为新的 WebSocket 附加上下文 data。它可在 WebSocket 处理程序中的 ws.data 属性上访问。 要为 ws.data 进行强类型定义,可在 websocket 处理对象里添加 data 属性,从而为所有生命周期钩子中的 ws.data 指定类型。
server.ts
以前,你可以像 Bun.serve<MyData>({...}) 一样,通过 Bun.serve 的类型参数指定 ws.data 的类型。由于 TypeScript 的一个限制,这种模式已被移除,改用 data 属性。
要从浏览器连接到此服务器,可以创建一个新的 WebSocket
browser.js
用户身份识别在页面上设置的 Cookie 会随 WebSocket 升级请求一起发送,并可在 fetch 处理程序的 req.headers 中访问。解析这些 Cookie 以识别连接的用户,并据此设置 data

发布/订阅

Bun 的 ServerWebSocket 包含原生的基于主题的发布-订阅 API。各个套接字可以通过 .subscribe() 订阅主题(使用字符串标识符指定),并使用 .publish() 向该主题的所有其他订阅者发送消息(不包括自身)。这种基于主题的广播 API 类似于 MQTTRedis Pub/Sub
server.ts
调用 .publish(data) 会将消息发送给某个主题的所有订阅者,但不包括调用 .publish() 的套接字。要向某个主题的所有订阅者发送消息,请使用 Server 实例上的 .publish() 方法。

压缩

使用 perMessageDeflate 参数启用逐消息压缩
server.ts
要压缩单条消息,请将一个 boolean 作为第二个参数传递给 .send()
要对压缩特性进行精细控制,请参考参考文档

背压管理

ServerWebSocket.send(message) 方法返回一个 number 表示操作结果。
  • -1 — 消息已入队,但存在背压(backpressure)
  • 0 — 由于连接问题,消息已丢弃
  • 1+ — 发送的字节数

超时和限制

默认情况下,Bun 会关闭处于空闲状态超过 120 秒的 WebSocket 连接。使用 idleTimeout 参数进行配置。
如果收到的消息大于 16 MB,Bun 也会关闭 WebSocket 连接。使用 maxPayloadLength 参数进行配置。

连接到 WebSocket 服务器

Bun 实现了 WebSocket 类。创建连接至 ws://wss:// 服务器的 WebSocket 客户端实例类似于浏览器中的用法。
在浏览器中,页面上设置的 Cookie 会随 WebSocket 升级请求一起发送。这是 WebSocket API 的标准功能。 在 Bun 中,你还可以直接在构造函数中设置自定义请求头。这是 Bun 对 WebSocket 标准的特有扩展。在浏览器中无法使用。
给套接字添加事件监听器的方法:

参考

See Typescript Definitions