数据通道

最近更新时间:2021-11-12 09:05:12

我的收藏
云游戏环境下,您无法与云端运行的应用直接进行通信,当您需要建立客户端与云端应用的通信时,可以使用我们提供的数据通道能力。

概念说明

腾讯云提供的数据通道能力使用 UDP 协议,数据通道调用逻辑如下图:



使用说明

前提条件

在使用云游戏提供的数据通道前,您需要保证您已按照以下步骤进行准备:
1. 云端应用创建 UDP 服务器,监听一个 UDP 端口(localhost 127.0.0.1 范围建议 10000 - 20000),并开始等待接收 UDP 包。
2. 云渲染的客户端调用云游戏 SDK 接口创建透传通道,SDK 接口里的目标端口参数应为 步骤1 中云端监听的端口。
3. 云渲染的客户端首先发送一个自定义数据包,云端应用 UDP 会收到请求,解析出本地代理端口。
4. 云端应用向 步骤3 拿到的本地代理端口发送自定义数据包,数据包将通过创建好的数据通道返回给客户端应用。

接口说明

请根据您的需要参考不同端 SDK 接口说明进行集成:

示例代码

前端(以 JS SDK 为例)
云端应用 UDP(以 C/C++ 为例)
(async _ => {
// 接收云端数据的回调
const onMessage = msg => {
console.log("收到云端应用回传数据:", msg);
};
// 定时重复创建直到成功
const result = await new Promise((resolve, reject) => {
const timer = setInterval(async _ => {
// 创建数据通道
const ret = await TCGSDK.createCustomDataChannel({
destPort: xxxx, onMessage //destPort: xxxx ,xxxx端口范围为10000~20000
});
if (ret.code == 0) {
resolve(ret);
clearInterval(timer);
}
}, 2000);// 2秒间隔
});
/*
* 判断是否成功
* result的结构{code: number, msg: string, sendMessage: Function }
*/
if (result.code == 0) {
// 随便发送一个绑定包,使云端应用的UDP服务能获得代理端口
result.sendMessage('test');
}
// 正常收发数据
result.sendMessage(`${custom_data}`);
})();

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;
}