画布事件回调
更新时间 2024/11/25 08:48:52
什么是画布事件回调?
用户使用画布时会与画布的服务端直接通信,所以用户在画布内的操作对画布的开发者是不透明的:除非进入画布并刚好处于对应视野,否则开发者无法感知用户的操作。 英飞画布 SDK 提供了画布回调机制,在用户使用画布时,主动通知开发者画布内发生的事件和事件的关键数据。目前英飞画布 SDK 支持的回调事件详见列表。
画布事件回调会在 webSDK 项目的回调地址后面附带 webSDK 项目的项目信息、回调事件名、身份验证信息等,以 POST
方式发送请求。事件类型和对应的数据格式见数据样例。回调地址格式如下:
回调地址?appId=APP_ID_VALUE&dataMd5=DATA_MD5_VALUE
&event=EVENT_NAME&eventTime=EVENT_TIME&signature=SIGNATURE_VALUE&validBegin=VALID_BEGIN_VALUE&validTime=VALID_TIME_VALUE
其中 event 字段和 eventTime 字段为事件回调的关键字段,分别表示回调事件类型和回调事件的发生时间。
如何接收事件回调?
准备一个公开的 post 接口作为回调地址
用户需要提前准备好一个公开的地址及端口作为回调地址,当英飞服务端处理事件回调时,会向回调地址会发送 POST 请求,请求体为 JSON 格式。 用户可以将数据按业务场景需要进行存储和处理。以下为记录画布回调事件并写入文件系统的 Node.js 代码示例:
- Node.js
// 文件记录画布回调事件
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(bodyParser.json());
// 接口 /report
app.post('/report', (req, res) => {
// TODO: 需要先对请求数据进行验证,确保数据来自英飞服务端
// 此处只针对回调事件提供相关数据处理示例
const now = new Date();
// 格式化当前时间为"年-月-日"的格式,用于文件名
const reportDate = `${now.getFullYear()}-${(now.getMonth() + 1)
.toString()
.padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
const reportFilename = `report-${reportDate}.txt`;
const reportPath = path.join(__dirname, 'reports', reportFilename);
// 格式化当前时间为"年-月-日 小时:分钟:秒"的格式,用于日志记录
const timestamp = `${reportDate} ${now
.getHours()
.toString()
.padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now
.getSeconds()
.toString()
.padStart(2, '0')}`;
// 确保 reports 文件夹存在
if (!fs.existsSync(path.join(__dirname, 'reports'))) {
fs.mkdirSync(path.join(__dirname, 'reports'));
}
// 创建日志条目
const logEntry = `Time: ${timestamp}, Url: ${req.url}, Body: ${JSON.stringify(req.body)}\n`;
// 将日志条目写入相应的报告文件
fs.appendFileSync(reportPath, logEntry);
res.status(200).send('Report saved');
});
// 启动服务
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
配置 APP 的回调事件
开发者在画布 SDK 控制台创建项目时可以配置回调地址(可选),用于接收画布事件回调数据。画布回调地址需要 http / https 协议的域名地址(公网可访问)。 项目配置页提供了修改回调地址的功能。新建的应用默认未配置回调事件,需要开发者在项目配置页勾选需要回调的事件,功能入口如下图所示:
利用事件回调能做什么?
开发者需要将实时回调的数据保存,利用数据内的关键内容可以实现多种业务功能如:
-
查看画布使用记录
利用会议 rtc 开始、会议 rtc 进行中、会议 rtc 结束等事件回调,统计会议情况。结合进入会议、结束会议等事件,实现参会情况统计。
-
分析统计用户行为
-
提取画布内文字信息
利用评论内容变更事件,生成评论弹幕。
画布回调事件与数据格式
用户进入白板
- 事件 event: board_accessed
- 事件别名: INFI_EVENT_TYPE_BOARD_ACCESSED
{
"data": [
{
"recordId": "HelloWorld",
"userId": "user_0",
"time": "时间戳"
}
]
}
用户修改白板
- 事件 event: board_modified
- 事件别名: INFI_EVENT_TYPE_BOARD_MODIFIED
{
"data": [
{
"recordId": "HelloWorld",
"userId": "user_0",
"time": "时间戳"
}
]
}
用户离开白板
- 事件 event: board_exited
- 事件别名: INFI_EVENT_TYPE_BOARD_EXITED
{
"data": [
{
"recordId": "HelloWorld",
"userId": "user_0",
"time": "时间戳"
}
]
}
会议 rtc 开始
- 事件 event: rtc_begin
- 事件别名: INFI_EVENT_TYPE_RTC_BEGIN
{
"data": {
"recordId": "HelloWorld",
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"title": "XXX的快速会议",
"vendor": 2, // 快速会议
"cname": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"startTime": "时间戳",
"endTime": "时间戳",
"host": "user_0",
"joiners": [],
"realEnd": false,
"currJoinerCnt": 0
}
}
会议 rtc 进行中
- 事件 event: rtc_ing
- 事件别名: INFI_EVENT_TYPE_RTC_ING
- 说明: 该事件会在会议结束前持续回调。
{
"data": {
"recordId": "HelloWorld",
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"title": "XXX的快速会议",
"vendor": 2,
"cname": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"startTime": "时间戳",
"endTime": "时间戳",
"host": "user_0",
"joiners": [
{
"userId": "user_0",
"mediaIds": [123],
"joinDur": 123456,
"editDur": 123456,
"mediaDur": 123456,
"audioNum": 1,
"userRole": 1
}
],
"realEnd": false,
"currJoinerCnt": 1
}
}
会议 rtc 结束
- 事件 event: rtc_end
- 事件别名: INFI_EVENT_TYPE_RTC_END
{
"data": {
"recordId": "HelloWorld",
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"title": "XXX的快速会议",
"vendor": 2,
"cname": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"startTime": "时间戳",
"endTime": "时间戳",
"host": "user_0",
"joiners": [
{
"userId": "user_0",
"mediaIds": [123],
"joinDur": 123456,
"editDur": 123456,
"mediaDur": 123456,
"audioNum": 1,
"userRole": 1
}
],
"realEnd": false,
"currJoinerCnt": 0
}
}
添加会议
- 事件 event: meeting_added
- 事件别名: INFI_EVENT_TYPE_MEETING_ADDED
{
"data": {
"coHosts": [],
"customField": "",
"host": "user_0",
"lockJoiners": [],
"lockState": 0,
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"planEnd": "时间戳",
"planJoiners": ["user_0"],
"planStart": "时间戳",
"recordId": "HelloWorld",
"title": "XXX的快速会议",
"type": 1
}
}
取消会议
- 事件 event: meeting_canceled
- 事件别名: INFI_EVENT_TYPE_MEETING_CANCELED
{
"data": {
"coHosts": [],
"customField": "",
"host": "user_0",
"lockJoiners": [],
"lockState": 0,
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"planEnd": "时间戳",
"planJoiners": ["user_0", "user_1", "user_2"],
"planStart": "时间戳",
"recordId": "HelloWorld",
"title": "XXX的快速会议",
"type": 1
}
}
邀请会议参会人
- 事件 event: meeting_invited
- 事件别名: INFI_EVENT_TYPE_MEETING_INVITED
{
"data": {
"coHosts": [],
"customField": "",
"host": "user_0",
"lockJoiners": [],
"lockState": 0,
"meetingId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"planEnd": "时间戳",
"planJoiners": ["user_2", "user_0", "user_1"],
"planStart": "时间戳",
"recordId": "HelloWorld",
"title": "XXX的快速会议",
"type": 1
}
}