@realsee/vr-signals API Documentation - v2.0.0
    Preparing search index...

    @realsee/vr-signals API Documentation - v2.0.0

    @realsee/vr-signals

    VR 信号通信库,用于在 VR 应用和父窗口之间建立双向通信。

    • 🔄 自动握手和连接管理
    • 📡 双向消息通信
    • 🚀 智能重试策略(指数退避 + 抖动)
    • 🔌 自动重连机制
    • 📝 详细的日志记录
    • 🎯 类型安全的 API
    • 🛡️ 企业级安全特性
    • 开箱即用的核心类型 - 无需传入泛型参数

    SDK 现在提供了核心类型支持,包含了必要的 Action 和 Event。这意味着你可以直接使用 SDK,无需定义自己的类型映射:

    SDK 现在支持动态注册和移除 Actions,无需在初始化时传入完整的 actionMap

    import { RealseeVRSignalsRemote } from '@realsee/vr-signals'

    const remote = new RealseeVRSignalsRemote({
    logLevel: 'INFO'
    })

    // 动态注册单个 Action
    remote.registerAction('setState', async (data) => {
    console.log('setState 被调用:', data)
    // data 包含 mode, longitude, latitude, fov 等 Five SDK 状态
    return { success: true, message: '状态已设置' }
    })

    // 批量注册 Actions
    remote.registerActions({
    'updateCamera': async (data) => {
    console.log('updateCamera 被调用:', data)
    // data.state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态
    return { success: true, message: '相机已更新' }
    },
    'tag.changeData': async (data) => {
    console.log('tag.changeData 被调用:', data)
    return { success: true, message: '标签已更新' }
    }
    })

    // 移除 Action
    remote.unregisterAction('tag.changeData')

    // 监听 Action 变化
    remote.onActionChange((event) => {
    console.log('Action 变化:', event)
    })

    // 获取统计信息
    const stats = remote.getActionStats()
    console.log('已注册 Actions:', stats.registered)
    import { RealseeVRSignalsClient } from '@realsee/vr-signals'

    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement
    })

    // 检查 Action 是否可用
    if (client.isActionAvailable('setState')) {
    // 安全调用
    const result = await client.send('setState', {
    mode: 'panorama',
    longitude: 0,
    latitude: 0,
    fov: 90
    })
    console.log('结果:', result)
    } else {
    console.log('setState 不可用')
    }

    // 监听 Action 可用性变化
    client.onActionAvailabilityChange('setState', (available) => {
    if (available) {
    console.log('setState 现在可用了!')
    } else {
    console.log('setState 不可用了')
    }
    })

    // 等待特定 Action 可用
    try {
    await client.waitForAction('setState', 5000)
    console.log('setState 可用,开始调用...')
    await client.send('setState', {
    mode: 'panorama',
    longitude: 0,
    latitude: 0,
    fov: 90
    })
    } catch (error) {
    console.log('等待超时:', error.message)
    }

    // 获取可用 Actions 列表
    const availableActions = client.getAvailableActions()
    console.log('可用的 Actions:', availableActions)
    import { RealseeVRSignalsClient, RealseeVRSignalsRemote } from '@realsee/vr-signals'

    // 客户端 - 无需泛型
    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: document.getElementById('vr-container') as HTMLDivElement,
    logLevel: 'INFO'
    })

    // 服务端 - 无需泛型
    const remote = new RealseeVRSignalsRemote({
    logLevel: 'INFO',
    actionMap: {
    setState(data) {
    console.log('State update:', data)
    // data 包含 mode, longitude, latitude, fov 等 Five SDK 状态
    return { success: true }
    },
    updateCamera({ state }) {
    console.log('Camera update:', state)
    // state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态
    return { success: true }
    }
    }
    })

    // 直接使用预定义的事件和动作
    client.on('stateSynced', (data) => {
    console.log('State synced:', data)
    // data 包含 mode, longitude, latitude, fov 等 Five SDK 状态
    })

    client.on('cameraUpdate', (data) => {
    console.log('Camera updated:', data.state)
    // data.state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态
    })

    client.on('tag.click', (data) => {
    console.log('Tag clicked:', data.data.title)
    })

    client.on('monitor.open', (data) => {
    console.log('Monitor opened:', data.data.name)
    })

    client.on('monitor.close', (data) => {
    console.log('Monitor closed:', data.data.name)
    })

    client.on('overlay.visible', (data) => {
    console.log('Overlay visibility:', data.visible)
    })

    // 发送动作
    client.send('setState', {
    mode: 'panorama',
    longitude: 0,
    latitude: 0,
    fov: 90
    })
    client.send('updateCamera', {
    state: {
    longitude: 0,
    latitude: 0,
    fov: 90,
    offset: { x: 0, y: 0, z: 0 }
    }
    })

    // 发送事件
    remote.sendEvent('stateSynced', { mode: 'editing', view: 'panorama' })
    remote.sendEvent('cameraUpdate', {
    state: {
    longitude: 0,
    latitude: 0,
    fov: 90,
    offset: { x: 0, y: 0, z: 0 }
    },
    userAction: false
    })

    SDK 包含了以下核心功能:

    • 状态管理: setState - 设置应用状态
    • 相机控制: updateCamera - 更新相机状态
    • 状态同步: stateSynced - 状态同步事件
    • 相机事件: cameraUpdate - 相机更新事件
    • 标签事件: tag.click - 标签点击事件
    • 监控事件: monitor.open, monitor.close - 监控开启/关闭事件
    • 覆盖层事件: overlay.visible - 覆盖层显示/隐藏事件

    如果你需要添加自定义功能,仍然可以使用泛型:

    import { RealseeVRSignalsClient, DefaultActionMap, DefaultEventMap } from '@realsee/vr-signals'

    // 扩展核心类型
    interface CustomActionMap extends DefaultActionMap {
    'custom.action': (data: { message: string }) => Promise<{ result: string }>
    }

    interface CustomEventMap extends DefaultEventMap {
    'custom.event': (data: { message: string }) => void
    }

    // 使用扩展的类型
    const customClient = new RealseeVRSignalsClient<CustomActionMap, CustomEventMap>({
    vrLink: 'http://localhost:3000/vr-app',
    element: document.getElementById('vr-container') as HTMLDivElement
    })

    // 使用核心功能
    customClient.on('cameraUpdate', (data) => {
    console.log('Camera updated:', data.state)
    })

    // 使用自定义功能
    customClient.on('custom.event', (data) => {
    console.log('Custom event:', data.message)
    })

    customClient.send('custom.action', { message: 'Hello' })

    重要:为了兼容 1.x 版本,2.x 版本默认禁用了严格的安全模式:

    • 默认允许所有域名的跨域通信
    • 这提供了与 1.x 版本的最大兼容性
    • 在生产环境中建议启用安全模式以提高安全性
    1. Origin 验证:验证消息来源域名
    2. 消息结构验证:验证消息格式和必需字段
    3. 时间戳验证:防止重放攻击
    4. 消息签名:可选的数字签名验证
    5. 严格模式:限制只允许可信域名
    6. 🆕 自适应策略:智能识别 iframe 和父级窗口的域名关系

    自适应策略vr-signals 的核心安全特性,能够智能识别和适应不同的域名关系:

    • 同源环境http://localhost:3000http://localhost:3000
    • 同域名不同端口http://localhost:3000http://localhost:1234
    • 同域名不同协议http://example.comhttps://example.com
    • 子域名关系https://app.example.comhttps://vr.example.com
    • 恶意域名https://app.example.comhttps://malicious-site.com
    1. 🎯 零配置:开发环境无需手动配置域名白名单
    2. 🔧 自动适应:自动处理 localhost 不同端口的情况
    3. 🌐 智能识别:自动识别同域名下的子域名关系
    4. 🛡️ 安全可靠:完全避免使用危险的通配符
    5. ⚡ 开箱即用:减少配置错误和安全漏洞
    const adaptiveClient = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:1234/vr-app',
    element: iframeElement,

    // 安全配置:完全自适应
    security: {
    strictMode: true, // 启用严格模式
    validateOrigin: true, // 验证消息来源
    validateSignature: false, // 开发环境不启用签名验证
    signatureKey: undefined
    }
    })
    const productionClient = new RealseeVRSignalsClient({
    vrLink: 'https://vr-app.example.com',
    element: iframeElement,

    // 安全配置:自适应 + 签名验证
    security: {
    strictMode: true,
    validateOrigin: true,
    validateSignature: true, // 启用消息签名验证
    signatureKey: 'your-secret-key' // 签名密钥
    }
    })
    npm install @realsee/vr-signals
    
    import { RealseeVRSignalsClient } from '@realsee/vr-signals'

    // 无需泛型参数,直接使用核心类型
    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement,
    logLevel: 'INFO',

    // 自定义握手重试策略
    handshakeRetryStrategy: {
    baseDelay: 500, // 基础延迟 500ms
    maxDelay: 5000, // 最大延迟 5s
    jitterRange: [0.85, 1.15] // 抖动因子范围
    },

    // 自定义重连策略
    reconnectStrategy: {
    baseDelay: 2000, // 基础重连延迟 2s
    maxDelay: 30000, // 最大重连延迟 30s
    jitterRange: [0.8, 1.2] // 抖动因子范围
    },

    shakehandRetryTimes: 10, // 握手重试次数
    enableAutoReconnect: true, // 启用自动重连
    maxReconnectAttempts: 5 // 最大重连次数
    })

    // 监听连接状态
    client.onConnectionStatusChange((status) => {
    console.log('Connection status:', status)
    })

    // 等待连接就绪
    client.onReady(() => {
    console.log('Client is ready!')
    })

    // 发送核心动作(无需类型声明)
    client.send('setState', {
    mode: 'panorama',
    longitude: 0,
    latitude: 0,
    fov: 90
    })
    client.send('updateCamera', {
    state: {
    longitude: 0,
    latitude: 0,
    fov: 90,
    offset: { x: 0, y: 0, z: 0 }
    }
    })

    // 监听核心事件(无需类型声明)
    client.on('stateSynced', (data) => {
    console.log('State synced:', data)
    // data 包含 mode, longitude, latitude, fov 等 Five SDK 状态
    })

    client.on('cameraUpdate', (data) => {
    console.log('Camera updated:', data.state)
    // data.state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态
    })

    client.on('tag.click', (data) => {
    console.log('Tag clicked:', data.data.title)
    })

    client.on('monitor.open', (data) => {
    console.log('Monitor opened:', data.data.name)
    })

    client.on('monitor.close', (data) => {
    console.log('Monitor closed:', data.data.name)
    })

    client.on('overlay.visible', (data) => {
    console.log('Overlay visibility:', data.visible)
    })
    import { RealseeVRSignalsRemote } from '@realsee/vr-signals'

    // 无需泛型参数,直接使用核心类型
    const remote = new RealseeVRSignalsRemote({
    logLevel: 'INFO',
    actionMap: {
    // 处理来自父窗口的核心请求
    setState(data) {
    console.log('Received state update request:', data)
    // data 包含 mode, longitude, latitude, fov 等 Five SDK 状态
    // 执行状态更新逻辑
    return { success: true }
    },

    updateCamera({ state }) {
    console.log('Received camera update request:', state)
    // state 包含 longitude, latitude, fov, offset 等 Five SDK 相机状态
    // 执行相机更新逻辑
    return { success: true }
    }
    }
    })

    // 等待连接就绪
    remote.onReady(() => {
    console.log('Remote is ready!')
    })

    // 发送核心事件到父窗口(无需类型声明)
    remote.sendEvent('stateSynced', {
    mode: 'panorama',
    longitude: 0,
    latitude: 0,
    fov: 90
    })

    remote.sendEvent('cameraUpdate', {
    state: {
    longitude: 0,
    latitude: 0,
    fov: 90,
    offset: { x: 0, y: 0, z: 0 }
    },
    userAction: false
    })

    remote.sendEvent('tag.click', {
    id: 'tag1',
    data: {
    id: 'tag1',
    title: '标签标题',
    description: '标签描述',
    type: 'info',
    extraData: '额外数据'
    }
    })

    remote.sendEvent('monitor.open', {
    id: 'monitor1',
    data: {
    id: 'monitor1',
    name: '监控1号',
    videoSrc: 'http://example.com/video1.mp4',
    type: 'camera',
    extraData: '监控数据'
    }
    })

    remote.sendEvent('monitor.close', {
    id: 'monitor1',
    data: {
    id: 'monitor1',
    name: '监控1号',
    videoSrc: 'http://example.com/video1.mp4',
    type: 'camera',
    extraData: '监控数据'
    }
    })

    remote.sendEvent('overlay.visible', { visible: true })

    如果你需要自定义类型,仍然可以使用泛型:

    // 定义自定义类型
    type CustomActionMap = {
    'custom.method': (data: { message: string }) => Promise<{ result: string }>
    }

    type CustomEventMap = {
    'custom.event': (data: { message: string }) => void
    }

    // 使用自定义类型
    const customClient = new RealseeVRSignalsClient<CustomActionMap, CustomEventMap>({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement
    })

    const customRemote = new RealseeVRSignalsRemote<CustomActionMap, CustomEventMap>({
    logLevel: 'INFO',
    actionMap: {
    'custom.method': async (data) => {
    return { result: `Processed: ${data.message}` }
    }
    }
    })

    握手重试使用指数退避策略,避免频繁重试:

    handshakeRetryStrategy: {
    baseDelay: 500, // 基础延迟时间(毫秒)
    maxDelay: 5000, // 最大延迟时间(毫秒)
    jitterRange: [0.85, 1.15] // 抖动因子范围
    }

    延迟计算示例:

    • 第1次重试:500ms × 2⁰ = 500ms
    • 第2次重试:500ms × 2¹ = 1000ms
    • 第3次重试:500ms × 2² = 2000ms
    • 第4次重试:500ms × 2³ = 4000ms
    • 第5次重试:500ms × 2⁴ = 5000ms(达到最大值)

    重连也使用指数退避策略:

    reconnectStrategy: {
    baseDelay: 2000, // 基础重连延迟时间(毫秒)
    maxDelay: 30000, // 最大重连延迟时间(毫秒)
    jitterRange: [0.8, 1.2] // 抖动因子范围
    }

    延迟计算示例:

    • 第1次重连:2000ms × 2⁰ = 2000ms
    • 第2次重连:2000ms × 2¹ = 4000ms
    • 第3次重连:2000ms × 2² = 8000ms
    • 第4次重连:2000ms × 2³ = 16000ms
    • 第5次重连:2000ms × 2⁴ = 30000ms(达到最大值)

    抖动策略用于避免多个客户端同时重试,减少网络拥塞:

    • 握手抖动:0.85-1.15 倍随机因子
    • 重连抖动:0.8-1.2 倍随机因子
    1. 必须启用严格模式strictMode: true
    2. 必须验证消息来源validateOrigin: true
    3. 建议启用消息签名validateSignature: true
    4. 无需配置域名白名单:系统自动适应
    security: {
    strictMode: true,
    validateOrigin: true,
    validateSignature: false // 开发环境可选
    }
    security: {
    strictMode: true, // 测试环境建议启用
    validateOrigin: true, // 建议验证来源
    validateSignature: false // 测试环境可选
    }
    • 🎯 零配置:无需手动配置域名白名单
    • 🔧 自动适应:自动处理 localhost 不同端口
    • 🌐 智能识别:自动识别同域名下的子域名关系
    • 🛡️ 安全可靠:完全避免使用危险的通配符
    • ⚡ 开箱即用:减少配置错误和安全漏洞
    选项 类型 默认值 描述
    vrLink string - VR 应用链接(可选)
    element HTMLElement - iframe 或容器元素(可选)
    logLevel LogLevel 'NONE' 日志级别
    handshakeRetryStrategy object 见下方 握手重试策略
    reconnectStrategy object 见下方 重连策略
    shakehandRetryTimes number 10 握手重试次数
    enableAutoReconnect boolean true 是否启用自动重连
    maxReconnectAttempts number 5 最大重连次数
    security object 见下方 安全配置
    选项 类型 默认值 描述
    baseDelay number 500 基础延迟时间(毫秒)
    maxDelay number 5000 最大延迟时间(毫秒)
    jitterRange [number, number] [0.85, 1.15] 抖动因子范围
    选项 类型 默认值 描述
    baseDelay number 2000 基础重连延迟时间(毫秒)
    maxDelay number 30000 最大重连延迟时间(毫秒)
    jitterRange [number, number] [0.8, 1.2] 抖动因子范围
    选项 类型 默认值 描述
    strictMode boolean false 是否启用严格模式(兼容 1.x 版本)
    validateOrigin boolean false 是否验证消息来源(兼容 1.x 版本)
    validateSignature boolean false 是否验证消息签名
    signatureKey string - 消息签名密钥

    SDK 现在提供了核心类型支持,包含以下功能:

    • 状态管理: setState - 设置应用状态
    • 相机控制: updateCamera - 更新相机状态
    • 状态同步: stateSynced - 状态同步事件
    • 相机事件: cameraUpdate - 相机更新事件
    • 标签事件: tag.click - 标签点击事件
    • 监控事件: monitor.open, monitor.close - 监控开启/关闭事件
    • 覆盖层事件: overlay.visible - 覆盖层显示/隐藏事件

    重要:本版本 (2.0.0-beta.3) 完全向后兼容旧版本,但建议迁移到新的 API。

    如果你正在使用 1.x 版本的 SDK,可能会遇到通信失败的问题。这是因为 2.x 版本默认启用了严格的安全模式。

    • 1.x 版本使用通配符 * 进行跨域通信
    • 2.x 版本默认启用严格的安全验证
    • 安全机制会拒绝来自不可信域名的消息

    方案 1:使用兼容性配置(推荐)

    import { RealseeVRSignalsClient, getV1CompatibilityConfig } from '@realsee/vr-signals'

    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement,
    security: getV1CompatibilityConfig() // 自动配置 1.x 兼容性
    })

    方案 2:手动禁用安全验证

    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement,
    security: {
    strictMode: false, // 禁用严格模式
    validateOrigin: false, // 禁用来源验证
    validateSignature: false // 禁用签名验证
    }
    })

    方案 3:自动检测环境

    import { RealseeVRSignalsClient, getAutoCompatibilityConfig } from '@realsee/vr-signals'

    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement,
    security: getAutoCompatibilityConfig() // 自动检测并配置
    })
    import { 
    getV1CompatibilityConfig, // 获取 1.x 兼容配置
    getAutoCompatibilityConfig, // 自动检测环境配置
    isV1Environment // 检测是否为 1.x 环境
    } from '@realsee/vr-signals'

    // 检测环境
    if (isV1Environment()) {
    console.log('检测到 1.x 版本环境,使用兼容配置')
    }
    • 方法名变化callAction()send()(旧方法仍可用,但会显示警告)
    • 属性变化subscribe → 直接使用 Client 实例(旧属性仍可用,但会显示警告)
    • 构造函数参数vrLinkelement 在类型定义中变为可选(运行时验证仍然存在)
    • 核心类型支持:无需泛型参数即可使用核心功能
    // 旧用法(仍然支持)
    const result = await client.callAction('setState', { mode: 'editing' })
    client.subscribe.on('cameraUpdate', handler)

    // 新用法(推荐)
    const result = await client.send('setState', { mode: 'editing' })
    client.on('cameraUpdate', handler)

    如果你正在使用旧版本的 VR Signals SDK,迁移到新版本非常简单:

    npm install @realsee/vr-signals@latest
    

    旧版本(需要泛型)

    interface MyActionMap {
    setState: (data: any) => void
    updateCamera: (data: { state: any }) => void
    }

    const client = new RealseeVRSignalsClient<MyActionMap>({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement
    })

    新版本(无需泛型)

    const client = new RealseeVRSignalsClient({
    vrLink: 'http://localhost:3000/vr-app',
    element: iframeElement
    })

    旧版本(需要泛型)

    interface MyActionMap {
    setState: (data: any) => void
    updateCamera: (data: { state: any }) => void
    }

    const remote = new RealseeVRSignalsRemote<MyActionMap>({
    logLevel: 'INFO',
    actionMap: {
    setState(data) {
    return { success: true }
    },
    updateCamera({ state }) {
    return { success: true }
    }
    }
    })

    新版本(无需泛型)

    const remote = new RealseeVRSignalsRemote({
    logLevel: 'INFO',
    actionMap: {
    setState(data) {
    return { success: true }
    },
    updateCamera({ state }) {
    return { success: true }
    }
    }
    })
    • [ ] 更新依赖到最新版本
    • [ ] 移除不必要的类型定义
    • [ ] 简化客户端初始化代码
    • [ ] 简化服务端初始化代码
    • [ ] 测试核心的事件和动作
    • [ ] 验证类型安全
    1. 向后兼容: 旧版本的泛型用法仍然完全支持
    2. 类型安全: 新版本提供完整的类型安全,无需额外配置
    3. 性能: 核心类型不会影响运行时性能
    4. 扩展性: 仍然可以使用泛型来扩展核心类型

    好消息! 2.0 版本默认兼容 1.x 版本,无需特殊配置。

    Client 版本 Remote 版本 兼容性 配置要求
    1.x 1.x ✅ 完全兼容 默认配置
    1.x 2.x ✅ 兼容 默认配置即可(无需特殊配置)
    2.x 1.x ✅ 兼容 默认配置即可
    2.x 2.x ✅ 完全兼容 可使用严格安全配置
    import { RealseeVRSignalsRemote } from '@realsee/vr-signals'

    // 默认配置已兼容 1.x Client,无需特殊配置
    const remote = new RealseeVRSignalsRemote({
    logLevel: 'INFO',
    actionMap: {
    setState(data) {
    return { success: true }
    }
    }
    })
    import { RealseeVRSignalsRemote, getV1CompatibilityConfig } from '@realsee/vr-signals'

    const remote = new RealseeVRSignalsRemote({
    security: getV1CompatibilityConfig(), // 显式声明兼容 1.x
    actionMap: { /* ... */ }
    })
    import { RealseeVRSignalsRemote, getV2DefaultConfig } from '@realsee/vr-signals'

    const remote = new RealseeVRSignalsRemote({
    security: getV2DefaultConfig('my-secret-key'), // 启用签名验证等高级安全特性
    actionMap: { /* ... */ }
    })

    详见 兼容性指南版本差异分析

    本项目使用 TypeDoc 自动生成 API 文档,并通过 npm 包发布。

    # 生成文档
    npm run docs

    # 启动本地服务器预览
    npm run docs:serve

    # 监听文件变化并自动重新生成
    npm run docs:watch

    MIT