VR 信号通信库,用于在 VR 应用和父窗口之间建立双向通信。
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 版本默认禁用了严格的安全模式:
自适应策略是 vr-signals 的核心安全特性,能够智能识别和适应不同的域名关系:
http://localhost:3000 ↔ http://localhost:3000 ✅http://localhost:3000 ↔ http://localhost:1234 ✅http://example.com ↔ https://example.com ✅https://app.example.com ↔ https://vr.example.com ✅https://app.example.com ↔ https://malicious-site.com ❌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] // 抖动因子范围
}
延迟计算示例:
重连也使用指数退避策略:
reconnectStrategy: {
baseDelay: 2000, // 基础重连延迟时间(毫秒)
maxDelay: 30000, // 最大重连延迟时间(毫秒)
jitterRange: [0.8, 1.2] // 抖动因子范围
}
延迟计算示例:
抖动策略用于避免多个客户端同时重试,减少网络拥塞:
strictMode: truevalidateOrigin: truevalidateSignature: truesecurity: {
strictMode: true,
validateOrigin: true,
validateSignature: false // 开发环境可选
}
security: {
strictMode: true, // 测试环境建议启用
validateOrigin: true, // 建议验证来源
validateSignature: false // 测试环境可选
}
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
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:使用兼容性配置(推荐)
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 实例(旧属性仍可用,但会显示警告)vrLink 和 element 在类型定义中变为可选(运行时验证仍然存在)// 旧用法(仍然支持)
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 }
}
}
})
好消息! 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