@netless/forge-room
v1.1.1
Published
`forge-room` 是 Netless Forge 平台的核心房间管理模块,提供实时的协作房间基础设施。它为房间内的用户提供包括白板、文档、幻灯片等在内的各种实时协作应用。
Readme
@netless/forge-room
forge-room 是 Netless Forge 平台的核心房间管理模块,提供实时的协作房间基础设施。它为房间内的用户提供包括白板、文档、幻灯片等在内的各种实时协作应用。
特性
- 🏠 房间管理: 提供完整的房间生命周期管理
- 🔄 实时同步: 基于 Yjs 的协作数据同步
- 📱 应用生态: 支持多种协作应用的插件化架构
- 👥 用户管理: 完整的用户状态和权限管理
- 🌐 多通信支持: 支持 RTM 和 Socket.IO 两种通信方式
- 💾 数据持久化: 自动保存和恢复房间状态
安装
npm install @netless/forge-room
# 或
pnpm add @netless/forge-room快速开始
1. 创建房间实例
构建房间实例之前,需要调用服务端 API 创建房间获取房间 token,参考 创建房间 API。
import { Room } from "@netless/forge-room";
import { RTMProvider_2_2 } from "@netless/forge-rtm";
import { WhiteboardApplication } from "@netless/forge-whiteboard";
import RTM from "agora-rtm";
// 创建 RTM 客户端
const rtmClient = new RTM('your-agora-app-id', 'user-id', {
token: 'your-rtm-token',
presenceTimeout: 4,
});
// 登录 RTM
await rtmClient.login();
// 创建 RTM 提供者
const rtmProvider = new RTMProvider_2_2(rtmClient);
// 创建房间实例
const room = new Room("room-id", rtmProvider);
// 注册应用(必须在加入房间前完成)
room.applicationManager.registerApplication(WhiteboardApplication);
// 加入房间
await room.joinRoom({
userId: "user-id",
nickName: "用户昵称",
roomToken: "room-token", // 白板房间 token
sdkConfig: {
region: "cn-hz",
appIdentifier: "appIdentifier"
},
windowManager: {
ratio: 1920 / 1080,
windowPosition: { x: 0.05, y: 0.05 },
windowSize: { width: 0.6, height: 0.6 },
},
writable: true,
verboseLog: false
});2. 启动应用
// 启动白板应用
const whiteboard = await room.applicationManager.launchApplication(
WhiteboardApplication,
{
width: 1920,
height: 1080,
defaultToolbarStyle: {
tool: "curve"
}
},
"MainWhiteboard" // 固定 appId,确保所有用户共享同一个白板
);
// 配置视图样式并挂载到 DOM
whiteboard.view.style.height = "100vh";
whiteboard.view.style.width = "100vw";
whiteboard.view.style.background = "#f9f9fc";
document.body.appendChild(whiteboard.view);API 文档
Room 类
构造函数
new Room(roomId: string, communicationProvider: CommunicationProvider)主要方法
joinRoom(options: JoinRoomOptions): Promise<void>
加入房间
参数:
userId: 用户 IDnickName: 用户昵称roomToken: 房间 tokensdkConfig: SDK 配置region: 区域配置(如 "cn-hz", "dev")appIdentifier: 应用标识符
windowManager: 窗口管理器配置writable: 是否可写(默认: true)verboseLog: 是否启用详细日志(默认: false)
leaveRoom(): Promise<void>
离开房间并清理资源
属性
applicationManager: 应用管理器windowManager: 窗口管理器(如果配置了)state: 房间当前状态isWritable: 当前用户是否可写
ApplicationManager
registerApplication(ApplicationClass: ApplicationClass): void
注册应用类到房间。必须在 joinRoom 之前调用。
launchApplication(ApplicationClass, config?, appId?): Promise<ApplicationInstance>
启动应用实例
参数:
ApplicationClass: 应用类config: 应用配置对象(可选)appId: 应用 ID(可选,默认使用随机 UUID)
on(event: 'launch' | 'terminal', listener: Function): void
监听应用生命周期事件
'launch': 应用启动时触发'terminal': 应用终止时触发
WindowManager
view: HTMLElement
窗口管理器的 DOM 视图
permissions: PermissionManager
窗口权限管理器
核心概念
appId 机制
房间内每个应用都有唯一的 appId,通过 launchApplication 的第三个参数指定。appId 划分了一块房间数据,房间里的所有用户都可以无冲突地访问和修改这块数据。
何时应该手动指定 appId?
- 当希望房间内所有用户共享同一个应用实例时(如主白板)
- 使用固定的 appId 确保数据一致性
何时应该用默认的 uuid?
- 当需要为每个用户创建独立的应用实例时
- 响应用户操作创建新的应用实例
View 管理
每个应用实例都有一个 view 属性,在 JavaScript 中对应一个 DOM 对象。forge-room 只负责管理应用的创建、数据同步和销毁,不包含任何 UI 组件,因此你需要:
- 对
view进行样式配置 - 将
view挂载到你的应用容器中 - 在
applicationManager的terminal事件中移除view以避免内存泄漏
// 正确的 view 清理方式
room.applicationManager.on('terminal', (appId, app) => {
console.log(`应用 ${appId} 已终止`);
app.view.remove(); // 在应用终止时自动移除 DOM 元素
});权限系统
房间层面提供了只读与可写的权限划分:
只读: 用户只能观看房间内容,无法进行任何修改操作。 可写: 用户可以进行内容创建、修改和删除等操作。
在可写的基础上, 每个 App 都有进一步详细的权限控制.
事件系统
// 监听应用事件
room.applicationManager.on('launch', (appId, app) => {
console.log(`应用 ${appId} 已启动`);
});
room.applicationManager.on('terminal', (appId, app) => {
console.log(`应用 ${appId} 已终止`);
app.view.remove(); // 清理 DOM
});
