有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
本节主要介绍如何使用数据通道与云端运行的应用直接进行通信。当业务需要建立客户端与云端应用通信,传输相关启动参数、指令、消息或其他数据时,例如透传微信名和头像信息至云端应用,可以使用数据通道能力。

时序图





步骤说明

1. 
务云端应用创建 UDP 服务,监听一个本地 UDP 端口(localhost 127.0.0.1 端口范围建议为 10000 - 20000),并开始等待接收 UDP 包。
2. 业务客户端调用 TCGSDK.start() 接口启动云渲染应用,SDK 完成应用连接后会触发回调 onConnectSuccess(),建议业务客户端在这之后创建数据通道。
3. 业务客户端调用 TCGSDK.createCustomDataChannel() 接口创建透传通道,接口里的目标端口参数应为 步骤1 中云端应用监听的端口,如果创建失败则重复本步骤直到创建成功。
4. 
据通道创建成功后,业务客户端可以调用 sendMessage() 发送业务自定义的数据包,云端应用 UDP 服务收到请求,解析出 UDP 来源地址。
5. 云端应用向 步骤4 拿到的 UDP 来源地址发送自定义数据包,数据包将通过创建好的数据通道回传,业务客户端可以在回调 onMessage() 接口中处理回传的数据包。

示例代码

业务前端(以 JS SDK 为例)
业务云端应用(以 C/C++ 为例)
let timer = null;

const { sendMessage, code } = await TCGSDK.createCustomDataChannel({
destPort: xxxx, // destPort 端口范围建议为 10000-20000
onMessage: (res) => {
console.log('CustomDataChannel onMessage', res);
// 收到该回调后,表示云端应用已成功拉起并成功向web 端发送数据,可以 clearInterval,之后正常发送数据
// clearInterval(timer);
},
});

// code 为 0 表示 web 端与云端数据通道已建立成功,但可能此时云端应用并未完全拉起(应用不能收发数据),web 端可以通过 setTimeout/setInterval/轮询等形式发送初始数据,直到云端应用正常回包。
if (code === 0) {
// 发送自定义数据
sendMessage('test');
// timer = setInterval(() => {
// sendMessage('test');
// }, 5000);
} else {
// 考虑重新创建数据通道
}
int main() {
int udp_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_socket_fd == -1) {
printf("socket failed!\\n");
return -1;
}

// 设置目的 IP 地址
struct sockaddr_in bind_addr = { 0 };
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(xxxx); // htons(xxxx) 中的端口范围建议为 10000-20000
bind_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); // 绑定 IP

// 绑定端口
int ret = bind(udp_socket_fd, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
if (ret < 0) {
perror("bind fail:");
close(udp_socket_fd);
return -1;
}

// 开始等待客户端消息
struct sockaddr_in upstream_addr = { 0 }; // 用来存放云渲染代理的地址
int len = sizeof(upstream_addr);
char buf[1024] = { 0 }; // 接收消息缓冲区
while (true) {
ret = recvfrom(udp_socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&upstream_addr, &len);
if (ret == -1) {
break;
}
// buf 为前端发来的消息 "test"
// 后续可以用 upstream_addr 回传消息给前端
const char* response = "response";
sendto(udp_socket_fd, response, strlen(response), 0, (struct sockaddr *)&upstream_addr, sizeof(upstream_addr));
}
return 0;
}

常见问题

数据通道创建成功,业务前端发送数据成功,但没有收到云端应用回复的数据?

TCGSDK.createCustomDataChannel() 接口调用成功表示业务前端与云端数据通道已建立成功,但可能此时云端应用并未完全拉起,业务前端可以通过 timeout/interval/轮询等形式发送自定义数据,确保云端应用成功拉起后正常接收到业务前端发送的自定义数据。只要数据通道创建成功,默认数据能发送成功。
在onMessage 回调中确定收到云端应用数据,可以取消轮询,之后正常发送数据。

可以收发的数据类型有哪些?

sendMessage()接口支持 string | ArrayBuffer 数据类型。

数据包传输大小是否有限制?

服务对传输数据包大小没有限制,但是需要注意 UDP 最大包长是 64KB,建议包大小应该小于 MTU 1500。如果包体过大,建议通过分包形式传输,如果太多数据上行容易导致拥塞影响体验。