有奖捉虫:行业应用 & 管理与支持文档专题 HOT
本文主要介绍使用 TIM 作为同步通道。

平台支持

iOS
Android
Windows
Mac OS
Web
小程序
?
?
?
?
?
?

注意事项

因为实时录制会以 TIMSDK 作为信令通道,同时是以自定义消息的 extension:'TXWhiteBoardExt' 为标识,所以在同步信令的时候需要注意以下四点:
1. 使用 TIMSDK 作为信令通道。
2. 关闭互动白板内置的信令通道(一定需要关闭,否则会收不到 onTEBSyncData 回调)。
3. 同步信令的时候发送的消息类型为自定义消息类型。
4. 自定义消息的 extension 字段必须为 TXWhiteBoardExt。

同步原理

?
?
?
监听 onTEBSyncData 事件(事件名以各端实际为准),将事件中回调的数据通过信令通道进行广播。
收到白板信令后,调用互动白板 addSyncData 接口(接口名以各端实际为准)进行同步。

代码集成

Mac/iOS
说明
以下示例为 TIM V2 版本代码,IM 的版本请尽量用新版本,具体请查阅 IM 的 更新日志
// 1. 将 TEduBoardInitParam 的 timSync 参数初始为 NO (关闭互动白板内置的信令通道)
TEduBoardInitParam *initParam = [[TEduBoardInitParam alloc] init];
initParam.timSync = NO; // 关闭互动白板内置的信令通道(一定需要关闭,否则会收不到onTEBSyncData回调)
_boardController = [[TEduBoardController alloc] initWithAuthParam:authParam roomId:_classId initParam:initParam];
?
// 2. 监听白板信令数据回调 onTEBSyncData,将数据发送给其他白板用户
- (void)onTEBSyncData:(NSString *)data {
V2TIMMessage *message = [[V2TIMManager sharedInstance] createCustomMessage:data desc:nil extension:@"TXWhiteBoardExt"];
if (message.customElem) {
message.customElem.extension = @"TXWhiteBoardExt";
}
[[V2TIMManager sharedInstance] getConversation:@"groupid" succ:^(V2TIMConversation *conv) {
if ([conv type] == V2TIM_GROUP) {
BOOL onlineUserOnly = ![[conv.groupType lowercaseString] isEqualToString:@"avchatroom"];
[[V2TIMManager sharedInstance] sendMessage: message
receiver: nil
groupID: conv.groupID
priority: V2TIM_PRIORITY_HIGH
onlineUserOnly:onlineUserOnly
offlinePushInfo:nil
progress:nil succ:^{
// 发送 IM 消息成功
} fail:^(int code, NSString *desc) {
// 发送 IM 消息失败,建议进行重试
}];
}
?
} fail:^(int code, NSString *desc) {
// 获取回话失败
}];
?
}
?
// 3. 监听IM的消息回调,在收到其他用户的白板信令时,将消息传递给白板
// 注意: 自己操作触发的信令,不需要再同步给本人
[_boardController addSyncData:data];
Android
说明
以下示例为 TIM V2 版本代码,IM 的版本请尽量用新版本,具体请查阅 IM 的 更新日志
// 1. 将 TEduBoardInitParam 的 timSync 参数初始为 NO (关闭互动白板内置的信令通道)
TEduBoardController.TEduBoardInitParam initParam = new TEduBoardController.TEduBoardInitParam();
initParam.timSync = false; // 关闭互动白板内置的信令通道(一定需要关闭,否则会收不到onTEBSyncData回调)
?
// 2. 监听白板信令回调 onTEBSyncData,将信令发送给其他白板用户
@Override
public void onTEBSyncData(String data) {
final V2TIMMessage message = V2TIMManager.getMessageManager().createCustomMessage(data.getBytes(), "", "TXWhiteBoardExt".getBytes());
if (message.getCustomElem() != null) {
message.getCustomElem().setExtension("TXWhiteBoardExt".getBytes());
}
V2TIMManager.getConversationManager().getConversation("groupid", new V2TIMValueCallback<V2TIMConversation>() {
@Override
public void onSuccess(V2TIMConversation v2TIMConversation) {
if (v2TIMConversation.getType() == V2TIMConversation.V2TIM_GROUP) {
boolean onlineUserOnly = !(v2TIMConversation.getGroupType().toLowerCase().equals("avchatroom"));
V2TIMManager.getMessageManager().sendMessage(message, null, "groupid", 1, onlineUserOnly, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onSuccess(V2TIMMessage v2TIMMessage) {
// 发送 IM 消息成功
}
?
@Override
public void onError(int i, String s) {
// 发送 IM 消息失败,建议进行重试
}
?
@Override
public void onProgress(int i) {
?
}
});
}
}
?
@Override
public void onError(int i, String s) {
// 获取回话失败
}
});
}
?
// 3. 在收到其他用户的白板信令时,将信令透传给白板
// 注意: 自己操作触发的信令,不需要再同步给本人
mBoard.addSyncData(data);
Windows
以下代码为演示代码,最新 TIM 相关接口请参考 TIM V2 创建自定义消息TIM V2 消息发送TIM V2 消息回调,按以下步骤进行接入。
// 引入IM SDK头文件
#include "TIMCloud.h"
?
// 这里为了演示方便,使用ostringstream来构造JSON串,生产环境建议使用第三方JSON库来生成JSON串
#include <iostream>
#include <sstream>
#include <string>
?
?
// 1. 将 TEduBoardInitParam 的 timSync 参数初始为 NO (关闭互动白板内置的信令通道)
TEduBoardInitParam initParam;
initParam.timSync = false; // 关闭互动白板内置的信令通道(一定需要关闭,否则会收不到onTEBSyncData回调)
boardCtrl->Init(authParam, ROOM_ID, initParam); // 使用上面构造的初始化参数
?
// 2. 监听白板信令回调 onTEBSyncData,将信令发送给其他白板用户
virtual void onTEBSyncData(const char * data) override {
//使用自定义信令通道,发送 data 给其他白板用户
std::string message = data;
std::ostringstream json;
json << "{";
json << "\\"" << kTIMMsgElemArray << "\\":";
json << "[{";
json << "\\"" << kTIMMsgPriority << "\\": " << kTIMMsgPriority_High << ","; // 设置消息优先级为高
json << "\\"" << kTIMElemType << "\\": " << kTIMElem_Custom << ","; // 消息类型为自定义消息
json << "\\"" << kTIMCustomElemExt << "\\": \\"TXWhiteBoardExt\\","; // 扩展字段信息
json << "\\"" << kTIMCustomElemData << "\\": \\"" << message << "\\","; // 消息内容为白板数据
json << "}]";
json << "}";
int ret = TIMMsgSendNewMsg("课堂id", kTIMConv_Group, json.str().c_str(), [](int32_t code, const char *desc, const char *json_param, const void *user_data) {
if (ERR_SUCC == code) { // 消息发送成功
//信令发送成功后调用 addAckData(data),确认数据发送状态
} else { // 消息发送失败,建议进行重试
}
}, nullptr);
if (ERR_SUCC != ret) { // 消息发送失败,建议进行重试
?
}
}
?
// 3. 在收到其他用户的白板信令时,将信令透传给白板
// 注意: 自己操作触发的信令,不需要再同步给本人
boardCtrl->AddSyncData(data);
Web
以下代码为演示代码,最新 TIM 相关接口请参考 TIM 创建自定义消息TIM 消息发送TIM 消息回调,按以下步骤进行接入。
// Web没有内置TIM通道,不需要额外关闭内置TIM通道。
// 1. 在 onTEBSyncData 回调里,将数据发送给其他白板用户
teduBoard.on(TEduBoard.EVENT.TEB_SYNCDATA, data => {
const message = tim.createCustomMessage({
to: '课堂ID',
conversationType: TIM.TYPES.CONV_GROUP,
priority: TIM.TYPES.MSG_PRIORITY_HIGH, // 因为im消息有限频,白板消息的优先级调整为最高
payload: {
data: JSON.stringify(data),
description: '',
extension: 'TXWhiteBoardExt',
},
});
// 发送消息
tim.sendMessage(message).then(() => {
// 发送成功
//信令发送成功后调用 addAckData(data),确认数据发送状态
}, (error) => {
// 发送失败,建议进行重试
});
});
// 2. 监听im的消息接收事件,在收到其他用户的白板信令时,将信令透传给白板(addSyncData)
// 注意: 自己操作触发的信令,不需要再同步给本人;以下代码this.im,this.userId,teduBoard请以实际的业务变量为准
this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, (event) => {
? const messages = event.data;
? const groupId = String(this.classInfo.classId);
? messages.forEach((message) => {
? ? // 群组消息
? ? if (message.conversationType === TIM.TYPES.CONV_GROUP) {
? ? ? if (message.to === groupId) { // 如果是当前群组
? ? ? ? const elements = message.getElements();
? ? ? ? if (elements.length) {
? ? ? ? ? elements.forEach(async (element) => {
? ? ? ? ? ? if (element.type === 'TIMCustomElem') { // 自定义消息
? ? ? ? ? ? ? if (element.content.extension === 'TXWhiteBoardExt') { // 是白板的自定义消息
? ? ? ? ? ? ? ? if (message.from != this.userId) { // 并且发消息的人不是自己
// 将白板信令设置给白板
? ? ? ? ? ? ? ? ? teduBoard.addSyncData(data);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? });
? ? ? ? }
? ? ? } else {
? ? ? ? // 其他群组消息自行处理,在互动白板的场景中可以忽略其他群组的消息
? ? ? }
? ? } else if (message.conversationType === TIM.TYPES.CONV_C2C) { // C2C消息
? ? ? // c2c消息在互动白板的场景中可以直接忽略
? ? }
? });
});
?


http://www.vxiaotou.com