Live 是 如视开发者中心 VRTC 服务 的核心客户端 Web SDK,搭配 Live Container SDKs(iOS/Android/微信小程序)和 Live API 可以快速实现实时同屏、实时语音、IM 等功能。
通常以键值对的形式表现——键为界面模块名字,值为该模块的状态信息。
比如帧数据{"popupPanel": { hidden: true }}
表示界面交互中有个弹窗面板,我们命名为popupPanel
,它有个hidden
状态,true
表示其正处于隐藏状态。
您可以理解 帧数据 是 快照 的子集,通过某时刻的"快照"信息能够还原该时刻的用户界面所有状态。
需注意的是 Live 并不包含 RTC 功能的实现,需借助客户端原生能力的支持。更多细节详见后文 RTC 协议 部分。
可以通过 Node 包管理工具 npm 或 yarn 安装Live:
# npm
npm i @realsee/live
# yarn
yarn add @realsee/live
简单使用样例(先不考虑实时语音能力):
import { createLive } from '@realsee/live'
const live = createLive({
url: 'wss://ws-access.realsee.com/***/?=xxx' /* 连接 WebSocket 服务的 URL */,
getTicket: async () => {
/* 获取带看"门票"的回调函数 */
},
})
在创建 live
实例时配置了两个参数:
url
:连接 WebSocket 服务的 URL,如果在创建 live
实例阶段并不知道 URL ,您可以在合适的时机通过 live.connect({ url })
方法进行 WebScoket 连接。getTicket()
:是一个异步回调函数,其返回值是连接 WebScoket 服务的 **"门票"**,关于如何获取 ticket
请查阅 VR 带看 API。关于
createLive()
函数的更多参数配置请参考 LiveOptions 。
获取实例 live
之后,可以做很多有趣的事情。但在讲述详细用途之前,先简单介绍下 Live 中的 消息系统。
Live 核心职责是借助 WebSocket 长链双工通信能力实现多端用户的同屏连线。用户间的通信都是基于 WebSocket 消息。
Live 将消息分为帧数据
、广播
、房间信息
三类。针对每一类信息提供相应的发送、接收 API,更多 API
细节请参考 Live API 文档 。
帧数据 是进行同屏的信息载体,由用户自行定义当前场景中哪些信息用以同屏,将这些信息组织成 {key: value}
的形式即可。
广播消息 用以房间成员之间以事件的形式指定某个用户向其发送自定义广播消息。如:主持人向观众发送问候消息。
房间信息 为内置消息体,由 WebSocket 服务主动推送,包括房间状态、当前用户及参与用户列表等。部分信息也可通过 Live 提供的更新方式进行修改。
当前 UI 交互状态的同步:
以 Five 同屏为例
// 发送本地 帧数据 (Five State)
live.sendKeyframe('five', { panoIndex: 13 })
// 接收远程 帧数据 (Five State)
live.keyframes.on('five', (newState, prevState) => {
// 可以拿最新的 `newState` 更新本地 UI 状态
})
您也可以通过 live.snapshot
属性来获取当前所有序列帧数据的"快照"。
Live 有会话房间的概念,当您成功连接 WebSocket 服务之后等同于您作为一个用户加入了一个房间。此房间用户除了您之外还会有其他用户,您可以通过如下方式获取或更新用户信息:
// 属性:获取本地用户信息
live.selfInfo
// 属性:获取当前房间内所有用户列表
live.userList
// 方法:更新本地用户信息
live.setSelfInfo({})
// 事件:本地用户信息发生变更
live.on('selfInfoUpdate', (userInfo) => {})
// 事件:房间用户列表信息发生变更
live.on('userListUpdate', (userList) => {})
除了帧数据和房间信息之外,还可以用事件的形式向房间内的其他用户广播消息:
live.broadcast(data /* 广播的数据 */, ['user_id_1', 'user_id_2'] /* 收到此用户的userId */)
此时,房间内用户 Id 为 user_id_1
、user_id_2
的用户会收到此广播消息(其他用户无感知):
live.on('broadcast', (data /* 广播的数据 */) => {})
更多的例子请查看 Live API 文档 。
Live 提供 WebSocket 事件
、live 事件
和 RTC 事件
三类异步事件的监听。
其中, WebSocket 事件
、live 事件
都可以通过 live.on('/*事件名*/', /*事件回调*/)
的方式监听。
比如监听 WebSocket 状态发生变更:
live.on('ws.readyStateUpdate', (readyState: WebSocketState) => {
console.log(readyState) // readyState 即是最新的 WebScoket 状态
})
ws.beforeConnect(reConnect?: number): void
WebSocket 完成连接之后。
ws.afterConnect(reConnect?: number): void
WebSocket 完成连接之前。
ws.readyStateUpdate(readyState: WebSocketState): void
WebSocket 完成状态发生变更。
WebSocket 连接状态枚举表:
状态名称 | 状态描述 |
---|---|
NOTINITIALIZED | 未被初始化 |
CONNECTING | 正在连接中 |
OPEN | 连接成功 |
CLOSING | 关闭中 |
CLOSED | 关闭成功 |
Live 前后端服务交互是基于 WebSocket 长链接的。一次带看成功进入、退出的标识由 WebSocket 的状态 OPEN
、CLOSED
体现。 因此,所有 VRTC 相关的事件处理逻辑应保证在OPEN
事件之后进行。
broadcast(evtMsg: Record<string, any>, frontRequestId: string): void
接收其他用户的广播消息。
builtinEvent(builtinMsg: BuiltinMsg): void
接收服务端推送的内置事件消息。
keyframes(keyframes: Partial<Snapshot>, frontRequestId: string): void
接收其他用户的帧数据。
readyKeyframeSync(lastKeyframe: Partial<Snapshot>): void
表明帧同步行为已就绪。
selfInfoUpdate(userInfo: UserInfo, frontRequestId: string): void
自身的信息发生变更。
userListUpdate(userList: UserInfo[], frontRequestId: string): void
用户列信息表发生变更。
live
实例提供了很多诸如live.connect()
、live.broadcast()
、live.sendKeyframe()
等方法,这些方法都是异步反馈且可能会影响房间内的其他用户。
您可以通过监听以上事件来获知这些影响。
需要注意的是 readyKeyframeSync
事件是可进行帧同步的节点标识,收到此事件后您的帧同步行为才生效。
error(error: Error): void
异常事件。
initWillStart(): void
即将初始化事件。
inited(): void
初始化完成事件。
joinWillStart(): void
即将加入语音房间事件。
joined(): void
成功加入语音房间事件。
userVolumes(userVolumes: UserVolume[]): void
房间内每个说话用户的音量。
weakNetwork(): void
弱网提醒事件。
live.$RTC
实例需满足 RTC 协议,其事件通过 live.$RTC.on('/*事件名*/', /*事件回调*/)
方式来监听,比如监听语音房间内正在说话的用户及其音量:
live.$RTC.on('userVolumes', (userVolumes: UserVolume[]) => {
console.log(userVolumes) // userVolumes 正在说话的用户及其音量数据。
})
ws.error(error: WebSocketError): void
WebSocket 连接出现异常。WebSocket 错误状态枚举表:
错误字段 | 错误描述 | 触发场景 |
---|---|---|
Close | 错误类型枚举参照CloseEvent | 错误原因参照CloseEvent |
Error | ||
MicroAuth | 麦克风授权错误 | 语音功能获取麦克风授权失败 |
DuplicateConnect | 重复连接 | 使用相同的 WS 链接申请连接 |
IllegalURL | 非法的 WS 链接 | 传入的 WS 链接不合法 |
Unknown | 未知错误 | 其他未被枚举的错误原样返回 |
error(liveMsg: LiveMsg): void
服务端推送出现异常。与 WebSocket 通信的结构体LiveMsg
格式如下:
名称 | 类型 | 描述 |
---|---|---|
appId | string | |
code | string | 返回码,详情参照服务端 API Code 码表 |
command | 指令 | WebSocket 通信指令类型,详情请查看Live API 文档 |
data | Record<string, any> | 本条指令对应的业务数据 |
frontRequestId: | string | 前端的请求 ID,由 WS 服务原样透传回前端 |
message | string | 返回描述 |
requestId | string | 后端请求 ID |
roomCode | string | 带看房间号 |
triggerUserId | string | 触发指令的用户 ID |
当 WebSocket 推送的数据结构体不满足 LiveMsg
或者 code
值不为 SUCCESS
时会以 error
事件的形式抛出来。
error(error: Error): void
RTC 语音出现异常。RTC 语音不同容器或 RTC 解决方案不同,其错误信息内容可能不完全一致。
语音能力需依赖 WebView/Browser 容器,即需要容器端实现 RTC 能力。
为了方便开发者接入,如视开发者中心 VRTC 服务 为主流平台提供 容器 SDK 和 jsbridge-x 。
Live 通过 jsbridge-x 与 集成了容器 SDK 的客户端应用或微信小程序应用程序桥接,实现原生能力的调用。这个 jsbridge-x
实例需作为配置参数提供给createLive()
。
如果是 iOS/Android App(已接入如视 VRTC 容器 SDK)
import { JSBridgeApp } from '@realsee/jsbridge-x/lib/app'
import { createLive } from '@realsee/live'
import { VRWebViewRTC } from '@realsee/live/RTC/VRWebViewRTC'
const jsBridgeInstance = new JSBridgeApp()
const rtcInstance = new VRWebViewRTC({
jsBridge,
getVoiceSign: () => {},
})
const live = createLive({
rtc: rtcInstance,
getTicket: async () => '',
})
提供 RTC 实例配置参数之后,语音的连接、断开、重连等逻辑就托管给了 Live 。您可以通过 live 实例上的 $RTC
命名空间访问语音相关的状态和事件。
// 状态:用户是否成功加入语音房间
live.$RTC.joined
// 状态:用户麦克风状态
live.$RTC.micro
// 监听用户音量变化
live.$RTC.on('userVolumes', (userVolumes) => {})
Live 有完整的 TypeScript Generics
和 React Hooks 支持,如果您的技术栈基于 TypeScript
和 React
可以参考如下方式更优雅地使用 Live。
步骤一:新建文件 LiveReact.ts
并创建您自己的 LiveReact
实例。
import { createLiveReact } from '@realsee/live'
/** 定义帧数据快照结构 */
interface Snapshot {
/** 以 Five 状态快照为例 */
five: {
panoIndex: number
fov: number
mode: 'Panorama' | 'Model'
latitude: number
longitude: number
}
}
/** 通过 `createLiveReact()` 函数创建实例*/
const LiveReact = createLiveReact<Snapshot>({
getTicket: async () => '' /* 必须提供 */,
})
export default LiveReact
/** 如果您不喜欢 `LiveReact.LiveProvider` 这类编程习惯,可以将需要的函数"抛"出来 */
export const LiveProvider = LiveReact.LiveProvider
export const useConnect = LiveReact.useConnect
export const useKeyframe = LiveReact.useKeyframe
// export ..
步骤二:通过 LiveProvider
将 live
实例集成到 React
的 Context 上下文环境中。
import { LiveProvider } from './LiveReact'
ReactDOM.render(
<LiveProvider>
<RootApp />
</LiveProvider>,
containter
)
步骤三:在您的 React
函数组件中使用相关 Hooks
函数。
import { useConnect } from './LiveReact'
function ReconnectBtn() {
const connect = useConnect()
return <button onClick={() => connect()}>重新连接</button>
}
欢迎查看 Live API 文档 。
该文档由 TypeDoc 生成,您可以详细查看 API 使用方式、事件 Hooks 及数据结构定义等。