Skip to main content
Bun.serve() 支持服务器端 WebSocket,具有即时压缩、TLS 支持和 Bun 原生的发布-订阅 API。
⚡️ 7 倍吞吐量Bun 的 WebSocket 速度很快。对于一个在 Linux x64 上的简单聊天室,Bun 每秒可处理的请求数量是 Node.js + "ws" 的 7 倍。Bun 的 WebSocket 实现内部构建于 uWebSockets 之上。

启动 WebSocket 服务器

以下使用 Bun.serve 构建的服务器,会在 fetch 处理器中将每个传入的请求升级为 WebSocket 连接。套接字处理器在 websocket 参数中声明。
server.ts
Bun 支持以下 WebSocket 事件处理器:
server.ts
在 Bun 中,处理器每个服务器只声明一次,而不是每个套接字声明一次。你向 Bun.serve() 传递一个包含 open、message、close、drain 和 error 方法的单个 WebSocketHandler 对象。这与客户端 WebSocket 类不同,后者扩展了 EventTarget(onmessage、onopen、onclose)。客户端通常打开的套接字连接较少,因此基于事件的 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 上使用类型参数来指定 ws.data 的类型,例如 Bun.serve<MyData>({...})。由于 TypeScript 的一个限制,这种模式已被移除,改为使用 data 属性。
要从浏览器连接到此服务器,创建一个新的 WebSocket。
browser.js
识别用户页面上设置的 Cookie 会随 WebSocket 升级请求一起发送,并可在 fetch 处理器的 req.headers 中获取。解析它们以识别连接中的用户,并相应地设置 data。

发布/订阅

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

压缩

使用 perMessageDeflate 参数启用每条消息的压缩。
server.ts
要压缩单条消息,将 boolean 作为第二个参数传递给 .send()。
有关压缩特性的精细控制,请参阅参考。

背压

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

超时和限制

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

连接到 Websocket 服务器

Bun 实现了 WebSocket 类。要创建一个连接到 ws:// 或 wss:// 服务器的 WebSocket 客户端,创建一个 WebSocket 实例,就像在浏览器中一样。
在浏览器中,页面上设置的 Cookie 会随 WebSocket 升级请求一起发送。这是 WebSocket API 的标准功能。 在 Bun 中,你也可以直接在构造函数中设置自定义头部。这是 Bun 对 WebSocket 标准的专用扩展。在浏览器中不起作用。
为套接字添加事件监听器:

参考

查看 TypeScript 定义