通过 webview 使用白板
更新时间: 2024/07/24 13:59:48
本文介绍Android、iOS、Windows、macOS客户端如何通过 webview 使用互动白板的相关能力。
示例项目源码
详细的示例代码请参见互动白板示例项目源码。
实现方法
通过 webview 调用白板的 API 时序图如下图所示。
- webview 调用
webPageLoaded
接口,通知客户端 webview 脚本加载成功。
js{
action: 'webPageLoaded',
param: {}
}
-
客户端收到
webPageLoaded
之后,调用jsJoinWB
接口创建及加入白板房间。具体参数请参考下文 -
webview 调用
webGetAuth
接口向客户端请求提供 auth 信息,用于登录白板服务器。
js{
action: 'webGetAuth',
param: {}
}
- 客户端向应用服务器请求鉴权参数,然后发送
jsSendAuth
消息,返回 auth 给 webview。
js{
action: 'jsSendAuth',
param: {
code: 200, //若成功,返回200
nonce: 'xxxx', //长度小于128的随机字符串
curTime: Math.round(Date.now()/1000) //当前UTC时间戳,从1970年1月1日0点0分0秒开始到现在的秒数
checksum: checksum
}
}
- webview 通过
webJoinWBSucceed
事件,告知客户端加入白板房间成功。
请在收到该事件之后,再调用 jsDirectCall
、 jsGetState
等接口。
js{
action: 'webJoinWBSucceed',
param: {}
}
-
客户端通过
jsDirectCall
编辑白板。jsDirectCall
具体用法请参考下文 -
客户端调用
jsLeaveWB
接口通知 webview 退出白板房间。
js{
action: 'jsLeaveWB',
param: {}
}
- 退出成功后,webview 会给客户端发送
webLeaveWB
事件。客户端收到该事件后,应该销毁 webview
所有接口
WebView --> 客户端
事件 | 描述 | 处理建议 |
---|---|---|
webPageLoaded | 通知客户端 webview 已加载完毕 | 收到该事件后调用 jsJoinWB 加入房间 |
webGetAuth | 白板SDK向客户端请求鉴权参数 | 客户端向应用服务器请求鉴权参数,然后通过 jsSendAuth 返回 |
webGetAntiLeechInfo | 白板SDK向客户端请求防盗链参数 | 客户端向应用服务器请求防盗链参数,然后通过 jsSendAntiLeechInfo 返回 |
webJoinWBSucceed | 加入白板房间成功 | 开发者应该在等到该事件之后,再调用 jsDirectCall 、 jsGetState 等接口 |
webJoinWBFailed | 加入白板频道失败。 | 请根据错误信息对业务代码进行调整。客户端应退出webview |
webLeaveWB | 白板SDK告知客户端已退出白板房间 | 开发者应该在收到该事件之后,退出webview,回到上一应用界面 |
webLog | webview 运行时产生的日志。 | 建议客户端将这些日志保存下来,方便日后调试 |
webJsError | webview 内js运行异常。 | 客户端可根据此消息调试 |
webAppStateChange | 在初始参数中设置appStateToListen 数组,当数组中代表的状态改变时, webview 会发送webAppStateChange 给客户端。 |
无 |
webToolCollectionEvent | 工具栏触发事件 | docAdd 和docDelete 事件:客户端可以根据此事件通知应用服务器记录当前用户关联的文档iconClick 事件:客户端界面变更 |
webDirectCallReturn | jsDirectCall 调用的回调消息 | jsDirectCall 调用后,webview通过该事件将消息回传给客户端 |
webRoomStateChange | 房间状态变化的通知事件 | 可以不处理 |
webPageLoaded
webview页面加载完毕后,向客户端发送 webPageLoaded
事件。webview 收到该事件后,应该调用 jsJoinWB
加入房间
js{
action: 'webPageLoaded'
}
webGetAuth
白板 SDK 在登录,上传音视频、图片,课件时,需要云信鉴权信息。客户端收到 webGetAuth
后,应该向应用服务器请求鉴权参数,然后通过 jsSendAuth
返回
js{
action: 'webGetAuth'
}
webGetAntiLeechInfo
应用如果开启 URL 防盗链,则需要应用服务器获取防盗链参数。收到该消息后,客户端向应用服务器请求防盗链参数,然后通过 jsSendAntiLeechInfo 返回。bucket 和 object 分别为资源的桶名和对象名。 URL 防盗链的参数配置方法请参考: 点播-防盗链
js{
action: 'webGetAntiLeechInfo',
param: {
prop: {
bucket: string
object: string
},
url: string, // 不含防盗链的地址。回传拼接地址时使用
seqId: number // 序列号。每次请求都会递增。通过 jsSendAntiLeechInfo 返回时,需要带上请求的 seqId
}
}
webJoinWBSucceed
加入白板房间成功后,白板 SDK 会通过此消息告知客户端。客户端收到此消息后,才可以调用 jsDirectCall
js{
action: 'webJoinWBSucceed'
}
webJoinWBFailed
加入白板房间失败,白板 SDK 会通过此消息告知客户端。随此消息一起,有失败的 msg 以及 code。客户端应该保留这些信息并调试。另外,客户端收到加入失败的消息后,应该销毁webview
js{
action: 'webJoinWBFailed',
param: {
code: number,
msg: string
}
}
webLeaveWB
退出白板房间后,客户端会收到此消息。收到此消息后,客户端应该销毁 webview
js{
action: 'webLeaveWB'
}
webLog
webview 给客户端发送 webview 运行时产生的日志。建议客户端将这些日志保存下来,方便日后调试。
js{
action: 'webLog',
param: {
type: 'info' | 'error' | 'warn' | 'log' | 'debug',
msg: string
}
}
webJsError
webview 内js运行异常。客户端可根据此消息调试。
js{
action: 'webJsError',
param: {
msg: string
}
}
webAppStateChange
在初始参数中设置appStateToListen
数组,当数组中代表的状态改变时, webview 会发送webAppStateChange
给客户端。具体参数为:
js{
action: 'webAppStateChange',
param: {
name: string
data: res //更新后的应用状态, 这个值和drawPlugin.on('event:appState:change', (name, ...res))的res一样
}
}
webToolCollectionEvent
工具栏触发事件时,会给客户端发送webToolCollectionEvent
消息。目前工具栏共有三类事件:docAdd
, docDelete
, 以及iconClick
。
工具栏中docUpload
所代表的文档弹窗中,文档发生变化时,会触发docAdd
与docDelete
事件。客户端可以根据此事件通知应用服务器记录当前用户关联的文档。详情请参见文档与页面。
用户自定义工具栏按钮被点击时,会触发iconClick
事件,详情请参见自定义组件
jsinterface IDocEntity {
docId: string, //文档的唯一id,删除文档时使用
fileType: 'pdf' | 'ppt' | 'doc', //文档类型,会影响弹窗中文档的图标
name: string, //文档名称
showDelete?: boolean, //是否显示删除按钮,默认为不显示删除按钮
params: {
url: string,
width: number,
height: number
}[]
}
{
action: 'webToolCollectionEvent',
param: {
name: 'docAdd' | 'docDelete'
data: Array<IDocEntity>
}
}
{
action: 'webToolCollectionEvent',
param: {
name: 'iconClick',
toolName: 'custom-xxx',
option: undefined
}
}
{
action: 'webToolCollectionEvent',
param: {
name: 'iconClick',
toolName: 'custom-state-xxx',
option: {
state: string,
newState: string
}
}
}
webDirectCallReturn
客户端通过 jsDirectCall 调用白板 SDK API时,若参数中包含 seqId,则 webview 会通过 webDirectCallReturn 将结果返回给 webview
js{
action: 'webDirectCallReturn',
param: {
target: 'drawPlugin' | 'whiteboardSDK' | 'toolCollection'
funcName: string //请参考API文档,action为接口名称
result: res //接口函数调用后返回的数据
seqId: number | string
}
}
webRoomStateChange
webview 通过 webRoomStateChange
事件,向客户端同步房间连接状态。客户端可以根据该事件判断当前是否可以编辑。
js{
action: 'webRoomStateChange',
param: {
event: 'onwillreconnect' | 'onconnected' | 'onSyncStart' | 'onSyncFinish',
/**
* 如果当前处于连接状态,且同步已经完成,则isEditable为true。
* 注意,下面的参数并没有考虑drawPlugin.enableDraw是否设置为true。
*
* 客户端用户应该在接到webRoomStateChange, 且isEditable为true,且设置了drawPlugin.enableDraw(true)之后,才可以修改白板的内容
*/
isEditable: boolean
}
}
客户端 --> WebView
函数 | 描述 | 调用时机 |
---|---|---|
jsJoinWB | 加入白板房间 | 收到 webPageLoaded 后调用此接口加入房间 |
jsLeaveWB | 离开白板房间 | 通知 webview 退出白板房间 |
jsDirectCall | 直接调用白板 SDK 的接口 | 需要在收到 webJoinWBSucceed 后调用 |
jsSendAuth | 传入白板鉴权参数 | 收到 webGetAuth 后,通过该接口回复鉴权参数 |
jsSendAntiLeechInfo | 传入防盗链地址 | 收到 webGetAntiLeechInfo 后,通过该接口回复防盗链地址 |
jsJoinWB
收到 webPageLoaded 后调用此接口加入白板房间。其参数和 WhiteBoardSDK.getInstance 基本一致:WhiteBoardSDK.getInstance API文档。下面是具体的参数示例:
js{
action: 'jsJoinWB',
param: {
uid: number //任意正整数
nickname: string //非必须
debug: true | false, //是否需要打印详细日志。若不开启,仅打印 error 级别日志
channelName: string,
appKey: string,
platform: 'android' | 'ios' | 'pc' | 'mac' | 'pad' //会影响工具栏的布局
record: true | false, //是否需要录制白板
/**
* 设置白板的语言。默认为中文
* en: 英文
* zh: 中文
*/
lang?: 'en' | 'zh',
/**
* 指定客户端监听哪些白板状态变化。
* 请参考SDK接口中event:appState:change,查看能接收的状态
*
* 比如设置 appStateToListen: ['page'], 则所有page相关的变化都会通知客户端
*
* webview会通过webAppStateChange通知客户端该状态的最新数值
*/
appStateToListen?: Array<string>
/**
* 请参考SDK接口中WhiteboardSDK.getInstance中的drawPluginParams。
*
* 若需要开启防盗链,请设置:
* drawPluginParams: {
* appConfig: {
* nosAntiLeech: true,
* nosAntiLeechExpire: 7200 //过期时间,默认后台配置为2小时
* }
* }
*/
drawPluginParams: any
toolCollectionParams?: {
/**
* 是否显示工具栏。默认为true
*/
initShow: boolean,
/**
* 是否在加载动态ppt后,加载上一步,下一步ppt切换工具按钮。
* 默认为true。
*
* 当该选项为true时,加载ppt后,webview会自动在右下方的工具栏中添加“上一步”,“下一步”按钮
* 当切换到不含动态ppt的文档时,再自动移除该按钮。
*
* 如果用户想要自行控制加载ppt后的工具栏按钮加载逻辑,可以设置pptIcons为false
*/
pptIcons: boolean
}
}
}
jsLeaveWB
客户端调用 jsLeaveWB
接口通知 webview 退出白板房间。webview退出房间后,会发送 webLeaveWB
至客户端
js{
action: 'jsLeaveWB',
param: {}
}
jsDirectCall
在收到 webJoinWBSucceed
后,才可以使用 jsDirectCall
。
通过 jsDirectCall
直接操作白板 SDK 的 drawPlugin
、 toolCollection
、 whiteboardSDK
、 WhiteBoardSDKClass
对象。
如果jsDirectCall
的参数中设置了seqId
,webDirectCallReturn
返回结果时,会将seqId
一并返回。
请您自行维护seqId,并通过seqId
判断应该将序列号和哪一次jsDirectCall
匹配。
示例代码如下:
js{
action: 'jsDirectCall',
param: {
target: 'whiteboardSDK' | 'drawPlugin' | 'toolCollection' | 'WhiteBoardSDKClass'
funcName: string //请参考SDK API文档。funcName为函数名
seqId?: number | string
arg1?: any
arg2?: any
arg3?: any
arg4?: any
arg5?: any
}
}
例如调用undo
操作的示例代码如下:
js{
action: 'jsDirectCall',
param: {
target: 'drawPlugin',
funcName: 'undo'
}
}
开启编辑权限的示例代码如下:
js{
action: 'jsDirectCall',
param: {
target: 'drawPlugin',
funcName: 'enableDraw',
arg1: true
}
}
调用zoomTo
的示例代码如下:
js{
action: 'jsDirectCall',
param: {
target: 'drawPlugin',
funcName: 'zoomTo',
arg1: 0.3 , //缩放比例30%
arg2: true //动画过渡至目标位置
}
}
jsSendAuth
客户端收到 webGetAuth
后,通过调用应用服务器的 http 接口,计算鉴权参数,然后将鉴权参数返回给白板 SDK
js{
action: 'jsSendAuth',
param: {
code: 200, //若成功,返回200
nonce: 'xxxx', //长度小于128的随机字符串
curTime: Math.round(Date.now()/1000) //当前UTC时间戳,从1970年1月1日0点0分0秒开始到现在的秒数
checksum: checksum
}
}
jsSendAntiLeechInfo
客户端收到 webGetAntiLeechInfo
后,通过调用应用服务器的 http 接口,计算防盗链 url 地址,然后将 url 地址返回给白板 SDK。防盗链文档请参考: 点播-防盗链
js{
action: 'jsSendAntiLeechInfo',
param: {
code: 200,
seqId: number, // webGetAntiLeechInfo 中的 seqId,代表这次请求的序列号
url: `${param.url}?wsSecret=${res.data.wsSecret}&wsTime=${wsTime}`
}
}