JSPM

  • Created
  • Published
  • Downloads 53
  • Score
    100M100P100Q86502F
  • License ISC

Package Exports

  • @netless/forge-room
  • @netless/forge-room/dist/room.esm.js
  • @netless/forge-room/dist/room.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@netless/forge-room) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

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: 用户 ID
  • nickName: 用户昵称
  • roomToken: 房间 token
  • sdkConfig: 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 组件,因此你需要:

  1. view 进行样式配置
  2. view 挂载到你的应用容器中
  3. applicationManagerterminal 事件中移除 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
});