Monorepo 结构
本仓库包含多个包:
- 服务端(Go)(
packages/server):WebSocket 桥接的独立 Go 实现(推荐) - 服务端(Bun,已弃用)(
packages/server-bun):最初的 Bun/Node.js 实现,仅作参考保留 - SDK(
packages/sdk):用于连接桥接服务的 TypeScript/JavaScript 客户端 - 示例(
examples/):SDK 的使用示例
功能特性
- 基于角色的连接系统(服务端/客户端)
- 服务端向客户端广播消息
- SDK 可作为客户端接收事件,或以服务端角色生产事件
- 基于令牌的身份验证
- 支持断线重连
环境要求
- Bun v1.2.0 或更高版本(管理 monorepo 以及运行 SDK / Bun 服务端时必需)
- Go 1.23.0 或更高版本(仅从源码构建或运行 Go 服务端时需要;项目会选择 Go 1.24.2 工具链)
安装
您可以通过以下几种方式运行服务端:
- 预编译二进制文件(对非技术用户最简单)
- Go 服务端(易于部署,推荐)
laplace-event-fetcher桥接模式(追求稳定性时推荐)- Bun 服务端(已弃用,仅作参考)
- 源码(面向高级用户与开发者)
预编译二进制文件
如果您不熟悉编程或命令行工具,运行 LAPLACE Event Bridge 服务端最简单的方式,是从我们的 GitHub Releases 下载预编译二进制文件:
-
下载服务端
- 前往 GitHub Releases 页面
- 找到名称中带有
@laplace.live/event-bridge-server的最新版本 - 下载与您操作系统对应的文件:
- Windows:
leb-server-windows-x64.exe - macOS:
leb-server-darwin-arm64 - Linux(x64):
leb-server-linux-x64 - Linux(arm64):
leb-server-linux-arm64
- Windows:
-
赋予可执行权限(仅 macOS/Linux):
- 打开终端
- 进入下载文件夹:
cd ~/Downloads - 执行:
chmod +x leb-server-*(将 * 替换为实际的文件名)
-
运行服务端:
- Windows:双击
.exe文件 - macOS:在终端中执行
./leb-server-darwin-arm64 - Linux:在终端中执行
./leb-server-linux-x64(根据需要将x64替换为arm64)
- Windows:双击
服务端会启动,并在可以接受连接时输出一条提示信息
桥接服务端(Go)
推荐的桥接服务端现在是位于 packages/server 的单二进制 Go 应用。构建或运行它不需要 Bun,只需要 Go 工具链
完整文档见 packages/server/README.md,快速上手如下:
# Enter the Go module and run from source
cd packages/server
go run . --debug
# Or build a native binary
go build -o leb-server .
./leb-server --host 0.0.0.0 --auth "your-secure-token"服务端默认监听 http://localhost:9696
Event Fetcher 桥接模式
在最新版 laplace-event-fetcher(v2.2.0 及以上)中,您可以启用 WebSocket 桥接模式,让 event fetcher 兼作桥接服务端,以获得更好的稳定性。使用该模式时无需保持 LAPLACE Chat 控制台运行,它会替您同时充当 event fetcher 与桥接服务端
桥接服务端(Bun,已弃用)
最初的 Bun/Node.js 实现位于 packages/server-bun。它与 Go 版功能等价,但出于性能与部署便利性已被 Go 版取代。我们仍会为依赖它的用户继续提供
# Start the Bun server
bun run --cwd packages/server-bun start --debug --auth "your-secure-token"服务端对比
| 特性 | 桥接服务端(Go) | Event Fetcher 桥接模式 |
|---|---|---|
| 安装 | 单二进制文件或 Go 工具链 | 需要 LAPLACE Event Fetcher v2.2.0+ |
| 环境 | 本地(独立二进制文件) | 容器 |
| 部署 | 简单 - 单文件部署 | 需要有服务器持续运行 |
| 事件来源 | LAPLACE Chat 控制台或 SDK 服务端角色 | Event Fetcher 内置 |
| 复用本地连接 | 是 | 否 |
| 配置 | 命令行参数 | Event fetcher 配置 |
| 稳定性 | 取决于您的本地网络 | 更稳定 |
| 适用场景 | 个人项目集成、小规模使用 | 面向 MCN 机构的生产级大规模部署,或已在使用 event fetcher 的用户 |
LLM 提示词
把下面的提示词粘贴给你的 AI 助手,或者存进项目的 CLAUDE.md、AGENTS.md 这类规则文件,它就有了替你编写集成所需的全部背景。提示词以英文写成,方便各家模型理解;里面引用的文档地址都可以直接抓取
You are helping me build an integration on top of LAPLACE Event Bridge, the WebSocket
bridge that relays real-time Bilibili live events — chat messages, gifts, super chats,
guard purchases, stream state — from LAPLACE Chat (https://chat.laplace.live) to local
clients.
Before writing any code, fetch the reference documents listed at the end — they are
the single source of truth for event types, payload fields and the client API. Do
not rely on memory and do not invent names.
## Setup
- Install `@laplace.live/event-bridge-sdk`. It runs anywhere with `WebSocket` and
`fetch` globals: Node.js 22+, Bun and browsers. Event payload interfaces live in
its dependency `@laplace.live/event-types`.
- A bridge server must be running: either the `leb-server` binary fed by LAPLACE Chat
or an SDK v1.2.0+ producer using `role: 'server'`, or LAPLACE Event Fetcher v2.2.0+
in bridge mode (standalone). Default endpoint: `ws://localhost:9696`.
- Auth is optional: when the server was started with `--auth`, pass the same string
as `token`.
## Client
```ts
import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";
const bridge = new LaplaceEventBridgeClient({
url: "ws://localhost:9696", // default
token: "your-auth-token", // only when the server enables auth
});
bridge.on("message", (event) => {
console.log(`${event.username}: ${event.message}`); // typed as Message
});
const offAny = bridge.onAny((event) => console.log(event.type, event.origin));
await bridge.connect();
// later: offAny(); bridge.disconnect();
```
## Producer (Server Role)
SDK v1.2.0+ can instead occupy the event-producing server role. This connects to
a running standalone Event Bridge server; it does not start the bridge server itself.
```ts
const producer = new LaplaceEventBridgeClient({
url: "ws://localhost:9696",
token: "your-auth-token",
role: "server",
});
await producer.connect();
producer.send(event); // event must be a LaplaceEvent
```
Only server-role messages are broadcast. A client-role `send()` is acknowledged by
the bridge but is not relayed to other connections.
The bridge is one-way — servers broadcast, clients listen — and reconnection is
automatic. Handlers are typed from the event name. Every event carries `type`, `id`
and `origin` (the canonical room id — filter on it when one bridge serves several
rooms). The exact event names, payload fields and the rest of the client API live in
the reference below — look them up instead of guessing.
## Reference
Fetch these before writing code:
- https://laplace.live/chat/event-bridge.en.mdx — this page as raw Markdown: server
setup, SDK client and producer roles, connection state, room discovery
- https://chat.laplace.live/event-types/ — every event type and payload field
- https://github.com/laplace-live/event-bridge — server and SDK source with runnable
examplesSDK
SDK 提供了用于连接 event bridge 的类型安全客户端;它既能接收事件,也能以服务端角色生产事件
安装
npm install @laplace.live/event-bridge-sdk用法
import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";
const client = new LaplaceEventBridgeClient({
url: "ws://localhost:9696",
token: "your-auth-token", // If auth is enabled
});
// Connect to the bridge
await client.connect();
// Listen for specific events
client.on("message", (event) => {
console.log("Received message:", event);
});
// Listen for all events
client.onAny((event) => {
console.log("Received event:", event.type);
});连接选项
LaplaceEventBridgeClient 接受以下连接选项,所有选项均可省略:
Prop
Type
服务端角色
SDK v1.2.0 起也可以作为事件生产者连接。设置 role: 'server' 后,send() 发送的 LaplaceEvent
会由桥接服务广播给所有客户端:
import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";
const producer = new LaplaceEventBridgeClient({
url: "ws://localhost:9696",
token: "your-auth-token",
role: "server",
});
await producer.connect();
function broadcast(event: Parameters<typeof producer.send>[0]) {
producer.send(event);
}这里的服务端角色是连接到正在运行的独立 Event Bridge 服务端的事件生产端,并不会启动桥接服务本身。默认的
client 角色用于接收事件;它调用 send() 时,消息只会收到确认,不会转发给其他连接。Event Fetcher
桥接模式会在内部自行生产事件,并忽略心跳 pong 以外的传入消息,因此无法转发 SDK 生产端的消息
连接状态
onConnectionStateChange() 会在注册时立即以当前状态调用一次处理函数,此时 detail 可能为
undefined。后续状态变化会在可用时提供断开原因与当前重连次数:
client.onConnectionStateChange((state, detail) => {
console.log(state, detail?.reconnectAttempts);
if (detail?.closeEvent) {
console.log(detail.closeEvent.code, detail.closeEvent.reason);
}
});
console.log(client.getReconnectAttempts());getReconnectAttempts() 返回当前中断期间已经进行的重连次数;连接正常或空闲时为 0
Prop
Type
服务端角色、连接状态详情与 getReconnectAttempts() 需要 v1.2.0 或更高版本的
SDK
直播间发现
当服务端是运行在桥接模式下的 LAPLACE Event Fetcher 时,它会暴露一个 /info HTTP 端点,列出已配置的直播间。SDK 无需建立 WebSocket 连接即可获取它——适合让用户自行选择要接收哪些直播间
使用 client.getInfo() 方法(复用客户端的 url / token):
const client = new LaplaceEventBridgeClient({
url: "ws://localhost:9696",
token,
});
const info = await client.getInfo();
if (info) {
console.log(`Fetcher v${info.version} exposes ${info.rooms.length} room(s)`);
for (const room of info.rooms) {
console.log(`${room.roomId}: ${room.username ?? "unknown"}`);
}
} else {
// Plain Event Bridge server or an older fetcher — fall back to manual entry.
}也可以使用独立的 fetchInfo() 函数,它不需要客户端对象:
import { fetchInfo } from "@laplace.live/event-bridge-sdk";
const info = await fetchInfo({ url: "ws://localhost:9696", token, signal });当 /info 不可用时——旧版 fetcher、普通的 Event Bridge 服务端、请求被中止,或任何网络/解析错误——两者都会解析为 null(而不会抛出异常),因此调用方可以静默回退到手动输入直播间
返回的类型是 FetcherInfo 与 FetcherRoom,二者均由 SDK 导出:
import type { FetcherInfo, FetcherRoom } from "@laplace.live/event-bridge-sdk";
interface FetcherRoom {
status: number; // 0 when resolved, otherwise an error code (e.g. 404)
uid: number;
roomId: number; // Canonical room id; matches the `origin` field on incoming events
shortRoomId: number;
username: string | null;
}
interface FetcherInfo {
version: string;
uptime: string;
connectedAt: number;
websocketBridge: boolean;
websocketClients: number;
rooms: FetcherRoom[];
}直播间发现需要以桥接模式运行的 LAPLACE Event Fetcher v2.2.0+,以及 v1.1.0 或更高版本的 SDK
LaplaceEvent
LaplaceEvent 是 event bridge 系统的核心类型,表示 LAPLACE Chat 与已连接客户端之间交换的事件。每个事件都包含来自哔哩哔哩直播各类弹幕流的标准化数据
所有事件都有一个共同的 type 字段用于标识事件类别,以及各自事件类型特有的附加字段
事件类型的更多说明见 事件类型文档
使用场景
- 与 Discord、OBS、VTube Studio 集成
- 在您偏好的前端中创建自定义的弹幕布局
- 接入 streamer.bot、SAMMI 等第三方服务
- ……以及任何您能想到的其他场景
开发
SDK 发布流程
SDK(@laplace.live/event-bridge-sdk)遵循结构化的发布流程,并使用 changesets 管理版本
-
在
packages/sdk/中修改 SDK -
创建 changeset 以记录本次改动:
bunx @changesets/cli- 从包列表中选择
@laplace.live/event-bridge-sdk - 选择合适的版本递增方式(patch/minor/major)
- 写清楚本次改动的说明
- 从包列表中选择
-
提交改动,包含生成的 changeset 文件:
git add . git commit -m "feat(sdk): your change description"
许可证
AGPL 与 MIT
最終更新日:2026年9月19日