@realsee/vr-signals
Version:
vr 信号器
344 lines (272 loc) • 7.79 kB
Markdown
# 版本差异分析:1.0 vs 2.0
## 关键差异总结
### 1. 架构变化
#### 1.0 版本架构
```
Base
├── Subscribe (事件订阅)
├── MessageBridge (消息桥接)
└── actionMap (直接存储)
```
#### 2.0 版本架构
```
Base (继承 StandardEventTarget)
├── StandardEventTarget (标准事件系统)
├── StandardActionManager (动态 Action 管理)
├── MessageBridge (增强的消息桥接)
└── SecurityUtils (安全验证)
```
### 2. 事件系统差异
#### 1.0 版本
- 使用自定义的 `Subscribe` 类
- 通过 `client.subscribe.on()` 监听事件
- 事件系统简单直接
#### 2.0 版本
- 继承标准的 `EventTarget`
- 直接通过 `client.on()` 监听事件
- 支持标准的 `addEventListener` / `removeEventListener`
- **保留了 `subscribe` 属性用于向后兼容**
```typescript
// 1.0 用法
client.subscribe.on('cameraUpdate', handler)
// 2.0 用法(推荐)
client.on('cameraUpdate', handler)
// 2.0 兼容模式(仍然支持)
client.subscribe.on('cameraUpdate', handler) // subscribe === this
```
### 3. Action 管理差异
#### 1.0 版本
- Action 在构造函数中静态注册
- 存储在 `_actionMap` 中
- 无法动态添加/移除
#### 2.0 版本
- 引入 `StandardActionManager`
- 支持动态注册/移除 Actions
- Remote 端有独立的 `DynamicActionRegistry`
- Client 端有 `ActionAvailabilityManager`
**潜在兼容性问题**:
- 1.0 Client 不知道 2.0 Remote 的动态 Action 变化
- 需要在 Remote 端确保初始 actionMap 的兼容性
### 4. 安全机制差异
#### 1.0 版本
- **无安全验证机制**
- 直接处理所有消息
- 使用 `*` 作为通配符
#### 2.0 版本
- 引入 `SecurityUtils` 类
- Origin 验证
- 消息签名验证
- 严格模式
**默认配置(兼容 1.x)**:
```typescript
{
strictMode: false,
validateOrigin: false,
validateSignature: false
}
```
**潜在兼容性问题**:
- 如果安全配置不正确,可能拒绝 1.0 Client 的消息
### 5. 消息格式差异
#### 消息结构(基本一致)
```typescript
interface Message<T> {
type: T
uid: string
payload: any
fromId: string
toId: string | string[]
timestamp: number
}
```
#### 关键差异点
1. **toId 处理**
- 1.0: 简单检查 `toIds.indexOf(this.uuid) === -1 && toIds.indexOf('*') === -1`
- 2.0: 可能增加了额外的安全验证
2. **错误处理**
- 1.0: 简单的 Error 对象序列化
- 2.0: 更完善的错误处理和日志记录
### 6. 握手机制差异
#### 1.0 版本
- 简单的握手重试
- 固定延迟重试
- 通过 `shakehandRetryTimes` 控制次数
#### 2.0 版本
- 指数退避 + 抖动策略
- `handshakeRetryStrategy` 配置
- 更智能的重试机制
**兼容性**:
- 握手消息格式相同
- 重试策略不影响兼容性
### 7. API 差异
#### 方法名变化
| 1.0 | 2.0 | 兼容性 |
|-----|-----|--------|
| `callAction()` | `send()` | ✅ 2.0 仍支持 `callAction()` |
| `subscribe.on()` | `on()` | ✅ 2.0 仍支持 `subscribe.on()` |
#### 新增 API(2.0)
- `registerAction()` / `unregisterAction()`
- `isActionAvailable()`
- `waitForAction()`
- `onActionChange()`
- `getActionStats()`
## 导致通信异常的根本原因
### 问题 1:安全验证导致消息被拒绝
**症状**:1.0 Client 发送的消息被 2.0 Remote 拒绝
**原因**:
```typescript
// 2.0 MessageBridge 中可能有的安全检查
private validateMessage(message: Message): boolean {
if (this.options.security?.validateOrigin) {
// 验证来源 - 1.0 Client 可能不符合预期
if (!SecurityUtils.validateOrigin(message)) {
return false
}
}
return true
}
```
**解决方案**:
```typescript
// Remote 端必须禁用安全验证
const remote = new RealseeVRSignalsRemote({
security: {
strictMode: false,
validateOrigin: false,
validateSignature: false
}
})
```
### 问题 2:ActionMap 访问方式差异
**1.0 版本**:
```typescript
// Base.ts
public get actionMap() {
return this._actionMap
}
// MessageBridge.ts
const action = this.instance.actionMap?.[method]
```
**2.0 版本**:
```typescript
// Remote.ts
private actionRegistry: DynamicActionRegistry<ActionMap>
// 需要通过 registry 访问
const action = this.actionRegistry.get(method)
```
**潜在问题**:
- 如果 MessageBridge 仍然尝试访问 `instance.actionMap`,可能找不到 action
- 需要确保 MessageBridge 能正确访问 Remote 的 action registry
### 问题 3:事件分发机制差异
**1.0 版本**:
```typescript
// MessageBridge.ts
private onEventMessage = (ev: Message<'event'>) => {
const { eventName, eventData } = ev.payload
this.instance.subscribe.emit(eventName, eventData)
}
```
**2.0 版本**:
```typescript
// 继承自 StandardEventTarget
// 需要通过 dispatchEvent 或 emit
this.instance.dispatchEvent(new CustomEvent(eventName, { detail: eventData }))
```
**潜在问题**:
- 如果事件分发方式变化,1.0 Client 可能收不到事件
### 问题 4:初始化顺序差异
**1.0 版本**:
```typescript
constructor(options) {
this._actionMap = options?.actionMap || {}
this.initMessageBridge()
}
```
**2.0 版本**:
```typescript
constructor(options) {
// Base 构造函数
super(options)
// Remote 构造函数
this.actionRegistry = new DynamicActionRegistry()
if (options.actionMap) {
this.registerActions(options.actionMap)
}
}
```
**潜在问题**:
- MessageBridge 初始化时,actionMap 可能还未准备好
- 需要确保在握手前所有 actions 都已注册
## 兼容性改造清单
### 必须修复的问题
1. ✅ **安全配置默认值**
- 确保默认配置兼容 1.x
- 提供 `getV1CompatibilityConfig()` 函数
2. ⚠️ **ActionMap 访问兼容**
- MessageBridge 需要能访问 Remote 的 actionRegistry
- 或者在 Base 中暴露统一的 action 访问接口
3. ⚠️ **事件分发兼容**
- 确保 2.0 的事件系统能正确分发给 1.0 Client
- 验证 `subscribe` 属性的兼容性
4. ⚠️ **握手时序**
- 确保握手时所有 actions 已注册
- 避免 1.0 Client 调用时 action 未就绪
### 需要验证的功能
1. 基本通信
- 握手成功
- 消息收发正常
2. Action 调用
- 1.0 Client 调用 2.0 Remote 的 action
- 参数和返回值正确传递
3. Event 监听
- 1.0 Client 能收到 2.0 Remote 发送的事件
- 事件数据完整
4. 错误处理
- Action 执行错误能正确返回
- 网络错误能正确处理
## 测试场景
### 场景 1:基础通信测试
```typescript
// 1.0 Client
const client = new RealseeVRSignalsClient({
vrLink: 'http://localhost:3000',
element: iframe
})
client.subscribe.on('ready', () => {
console.log('Connected!')
})
// 2.0 Remote
const remote = new RealseeVRSignalsRemote({
logLevel: 'DEBUG',
security: getV1CompatibilityConfig(),
actionMap: {
setState(data) {
return { success: true }
}
}
})
```
### 场景 2:Action 调用测试
```typescript
// 1.0 Client
client.callAction('setState', { mode: 'panorama' })
.then(result => console.log('Success:', result))
.catch(error => console.error('Error:', error))
```
### 场景 3:Event 监听测试
```typescript
// 1.0 Client
client.subscribe.on('cameraUpdate', (data) => {
console.log('Camera update:', data)
})
// 2.0 Remote
remote.sendEvent('cameraUpdate', {
state: { longitude: 0, latitude: 0 }
})
```
## 下一步行动
1. **代码审查**:检查 2.0 MessageBridge 中的 action 访问逻辑
2. **兼容性修复**:实现必要的兼容层
3. **集成测试**:编写 1.0 Client + 2.0 Remote 的测试用例
4. **文档更新**:更新 COMPATIBILITY.md 文档
5. **发布新版本**:发布包含兼容性修复的版本