文档中心>应用云渲染>实践教程>从零开始搭建全真互联未来会场小程序

从零开始搭建全真互联未来会场小程序

最近更新时间:2024-12-04 15:28:22

我的收藏
腾讯2022数字生态大会在深圳宝安的国际会展中心举行,为了让更多云端观众也能参与,大会特别开设了“全真互联未来会场”,支持海量用户化身“阿凡达” 登录虚拟的会展空间,像体验3D大作一样参会,并与其他用户、AI 数智人实时互动。两天会期内,总计有13000多人进入了未来会场,观众累计体验时长超20万分钟。手机打开微信小程序搜索“腾讯全球数字生态大会-未来会场”,即可体验完整功能!









未来会场基于 Unreal Engine打造,场景精细、功能丰富,但用户无需下载,无需高端的手机配置,在小程序上即可享受高清、流畅的虚拟参会体验,这是通过接入应用云渲染产品来实现的。本篇文档将基于该案例,为您剖析如何接入应用云渲染产品,如何从零开始搭建这样一个全真互联未来会场小程序,整体流程可参考下图:




接入前:应用开发

首先,您需要打造一个可在 Windows 环境下稳定运行的应用程序,在应用层面开发实现必要的功能。
例如,全真互联未来会场应用程序内实现了以下功能:
支持通过键盘 WASD/上下左右来操控人物移动,鼠标左键拖动操控视角:可通过引入虚拟摇杆插件适配手机端操作(详细请参见 步骤2-前端-基础用法)。
支持多人在线互动:建立一个 服务器 主持多人会话,所有其他用户使用 部署至应用云渲染的客户端连接到该服务器。
多人视频、语音、文字聊天功能。
嵌入图片/视频/直播流、实现虚拟形象表情动作、场景内放烟花、灯光秀等更多功能和玩法。
说明:
以上功能不是接入应用云渲染的必要条件,您可以按需实现,应用云渲染对您应用内功能的具体实现没有特殊要求,您也无需在 Unity 或 Unreal Engine 中进行特殊配置。不过为了实现更好的终端用户体验,在技术接入阶段(步骤2)您可以对应用做些针对性的调整,如将应用设置为无边框模式并开启自适应桌面分辨率(具体请参见步骤2-前端-高级功能)。

步骤1:控制台部署应用并测试效果


1. 将应用程序包体通过控制台上传部署至云端(参考应用上传应用启动参数配置)。
2. 新建项目并关联上传的应用程序(参考新建项目)。
3. 在项目下购买并发 (参考 购买并发包)。
4. 进行效果测试
更多指引请参考快速入门控制台操作指南

步骤2:下载接入 Demo 搭建业务前端和后台

完成效果测试后,为了实现云渲染服务管理、更好的前端操作体验、小程序适配等,您还需要搭建自己的客户端程序以及后台服务,接入应用云渲染提供的各终端 SDK和后端 API ,我们提供接入 Demo帮助您快速实现业务上线。



以下将基于我们提供的 JS 接入 Demo后台 Demo,为您剖析前端和后台功能和用法,详细请查看本文 步骤2-前端部分 和 步骤2-后台部分。
步骤2一前端部分
步骤2—后台部分

前端部分

基础概念

由于小程序暂时不支持 WebRTC,所以我们可以开发一个 H5 页面,然后通过小程序的 web-view 组件加载云渲染画面。

基础用法 - 页面准备工作

在页面中引入初始化脚本(JS SDK 下载)。
<script src="path/to/sdk" charset="utf-8"></script>
或代码中 import。
import TCGSDK from 'path-to-TCGSDK';

基础用法 - 编写页面代码

1. 初始化 TCGSDK。
TCGSDK.init({...initOptions})
2. 在 onInitSuccess 回调中启动项目,获取 ServerSession。
onInitSuccess: async () => {
await StartProject();
}
3. 获取 ServerSession 成功,启动云渲染。如期望实现排队功能,可参考 排队功能
TCGSDK.start(ServerSession);
4. 启动成功后在移动端,模拟键鼠操作。
onTouchEvent: async (res) => {
// res type 为 array,array 长度代表当前手机屏幕触摸的手指数
// console.log('onTouchEvent', res);
// 针对单指触控操作
if (res.length === 1) {
const { id, type, pageX, pageY } = res.pop();
// console.log('onTouchEvent', id, type, pageX, pageY);
// 模拟将鼠标移到触摸点
TCGSDK.mouseMove(id, type, pageX, pageY);
// 判断 touchstart 发送鼠标左键按下
if (type === 'touchstart') {
TCGSDK.sendRawEvent({ type: 'mouseleft', down: true });
}
// 判断 touchend 或 touchcancel 发送鼠标左键抬起
if (type === 'touchend' || type === 'touchcancel') {
TCGSDK.sendRawEvent({ type: 'mouseleft', down: false });
}
}
}
5. 
引入摇杆插件,摇杆插件通常对应键盘 WASD/上下左右 按键
5.1 添加以下代码引入插件。
<script type="text/javascript" src="path/to/joystick.js"></script>
5.2 在 onConnectSuccess 回调函数中创建摇杆。
// 添加摇杆 plugin-point 为需要挂载插件的 element 的 ID
const j = new CloudGamingPlugin.joystick({
zone: document.querySelector('#plugin-point'),
});
应用云渲染效果测试体验页面;键鼠操作模拟、虚拟摇杆引入等基础功能演示
应用云渲染效果测试体验页面;键鼠操作模拟、虚拟摇杆引入等基础功能演示


完整代码如下:

注意替换 TCGSDK,Joystick plugin 的路径
<!doctype html>
<html>

<head>
<meta charset="utf-8" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" />
<title>腾讯云-云渲染-应用云渲染-从零实现腾讯云生态大会云渲染小程序</title>
<style>
* {
padding: 0;
margin: 0;
}

html,
body {
width: 100%;
height: 100%;
overflow: hidden;
font-family: '黑体', 'Microsoft YaHei', 'Arial', 'sans-serif';
}

#demo-container {
width: 100%;
height: 100%;
}
</style>
</head>

<body>
<div id="demo-container">
<div id="mount-point"></div>
</div>
<script type="text/javascript" src="path/to/tcg-sdk"></script>
<script type="text/javascript" src="path/to/joystick.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>
<script>
// 对于应用云渲染,后台服务接口 StartProject 其实就是后台串行调用了云API的 ApplyConcurrent + CreateSession
// 申请并发(ApplyConcurrent) https://cloud.tencent.com/document/api/1547/72827
// 创建会话(CreateSession) https://cloud.tencent.com/document/api/1547/72826
const StartProject = async () => {
const url = 'https://xxxx/StartProject'; // 后台端实现可以参考后台 demo 方案

// 其他选填参数可以参考 ApplyConcurrent 接口文档
const { data } = await axios.post(url, {
ProjectId: 'project-id', // 项目Id
UserId: 'user-id', // 用户Id,不同用户应该采用不同 UserId,同一UserId,会存在互踢现象
ClientSession: TCGSDK.getClientSession(),
});

console.log('%c StartProject res', 'color: blue; font-size: 14px', data);

const { Code, SessionDescribe: { ServerSession } } = data;

if (Code === 0) {
TCGSDK.start(ServerSession);
} else {
// 请求异常处理
}
}

// 云渲染接入功能流程说明可以参考 https://ex.cloud-gaming.myqcloud.com/cloud_gaming_web/docs/index.html
TCGSDK.init({
appid: 1234567,
mount: 'mount-point',
debugSetting: {
showLog: true,
},
// 连接成功回调
onConnectSuccess: async (res) => {
console.log('onConnectSuccess', res);
},
// 网络中断/被踢触发此回调
onDisconnect: (res) => {
console.log('onDisconnect', res);
// 添加摇杆 plugin-point 为需要挂载插件的 element 的 ID
const j = new CloudGamingPlugin.joystick({
zone: document.querySelector('#plugin-point'),
});
},
onWebrtcStatusChange: (res) => {
console.log('onWebrtcStatusChange', res);
},
// 移动端触摸,模拟发送 PC 上指令
onTouchEvent: async (res) => {
// res type 为 array,array 长度代表当前手机屏幕触摸的手指数
// console.log('onTouchEvent', res);
// 针对单指触控操作
if (res.length === 1) {
const { id, type, pageX, pageY } = res.pop();
// console.log('onTouchEvent', id, type, pageX, pageY);
// 模拟将鼠标移到触摸点
TCGSDK.mouseMove(id, type, pageX, pageY);
// 判断 touchstart 发送鼠标左键按下
if (type === 'touchstart') {
TCGSDK.sendRawEvent({ type: 'mouseleft', down: true });
}
// 判断 touchend 或 touchcancel 发送鼠标左键抬起
if (type === 'touchend' || type === 'touchcancel') {
TCGSDK.sendRawEvent({ type: 'mouseleft', down: false });
}
}
},
onInitSuccess: async (res) => {
console.log('%c onInitSuccess', 'color: red', res);

await StartProject();
}
});

</script>
</body>

</html>

高级功能 - 多点触控

移动端多点触控可以分为两种形式:
云端应用支持多点触控,支持触摸事件,可直接设置 init 参数 clientInteractMode: 'touch',SDK 回自动发送 touch 相关指令致应用。
云端应用不支持多点触控,仅支持鼠标键盘,可根据 onTouchEvent 回调,拿到对应触摸点坐标,发送 键盘/鼠标 指令完成业务逻辑。

高级功能 - 移动端自适应屏幕分辨率

因为移动端不同手机尺寸有不同分辨率,期望云渲染画面总是铺满手机屏幕需要根据不同手机尺寸,设置不同的推流分辨率。由于需要同时配置云上应用和前端页面,具体步骤请参见 技术接入-自适应分辨率

高级功能 - 屏幕旋转

对于应用云渲染场景,由于云端总是推横屏流(宽大于高),所以在移动端手机竖屏显示时候可设置屏幕旋转,则将横屏流旋转为竖屏显示。屏幕旋转也可以搭配摇杆使用,摇杆插件已做兼容。
提供以下两种方法:
(推荐使用)TCGSDK init 参数中设置 autoRotateContainer: boolean,自动旋转屏幕。业务方不需要任何操作,所有逻辑 TCGSDK 接管。
调用 TCGSDK.setVideoOrientation 方法,旋转屏幕。

高级功能 - 数据通道

如果期望实现 Web 页面与云上应用数据互传可以使用数据通道功能,例如透传微信名和头像信息至云端应用。数据通道相关逻辑建议在 onConnectSuccess 回调中执行,调用 createCustomDataChannel 接口,发送数据类型支持 string 和二进制数据。详细实现流程及代码可以参考 技术接入-数据通道
未来会场小程序;通过数据通道,将用户授权的微信名和头像信息透传至云端应用
未来会场小程序;通过数据通道,将用户授权的微信名和头像信息透传至云端应用


高级功能 - 排队功能

当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验。
排队逻辑涉及前后台,前端代码可参考 排队示例,签名逻辑可以根据业务需求决定是否添加,后台部分请查看本文 步骤2-后台-高级功能,更多详细内容请参见 技术接入-排队功能
未来会场小程序;用户排队效果
未来会场小程序;用户排队效果


后台部分

基础概念

业务需要搭建下自己的后台服务去调用应用云渲染云 API,才能为您的客户服务。业务后台主要负责启动应用关闭应用排队等功能。

基础用法 - 启动应用

1. 后台服务调用云渲染 API ApplyConcurrent() 锁定云渲染并发,收到成功回调后执行下一步。
nodejs 版本
Golang 版本
// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
const tencentcloud = require("tencentcloud-sdk-nodejs");

const CarClient = tencentcloud.car.v20220110.Client;

// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
const clientConfig = {
credential: {
secretId: "SecretId",
secretKey: "SecretKey",
},
region: "",
profile: {
httpProfile: {
endpoint: "car.tencentcloudapi.com",
},
},
};

const client = new CarClient(clientConfig);
const params = {
"UserId": "user-id",
"UserIp": "user-ip",
"ProjectId": "project-id"
};
client.ApplyConcurrent(params).then(
(data) => {
console.log(data);
},
(err) => {
console.error("error", err);
}
);
package main

import (
"fmt"

"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
car "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/car/v20220110"
)

func main() {
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
credential := common.NewCredential(
"SecretId",
"SecretKey",
)
// 实例化一个client选项,可选的,没有特殊需求可以跳过
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = "car.tencentcloudapi.com"
// 实例化要请求产品的client对象,clientProfile是可选的
client, _ := car.NewClient(credential, "", cpf)

// 实例化一个请求对象,每个接口都会对应一个request对象
request := car.NewApplyConcurrentRequest()
request.UserId = common.StringPtr("user-id")
request.UserIp = common.StringPtr("user-ip")
request.ProjectId = common.StringPtr("project-id")

// 返回的resp是一个ApplyConcurrentResponse的实例,与请求对象对应
response, err := client.ApplyConcurrent(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
fmt.Printf("An API error has returned: %s", err)
return
}
if err != nil {
panic(err)
}
// 输出json格式的字符串回包
fmt.Printf("%s", response.ToJsonString())
}
2. 后台服务调用云渲染 API CreateSession() ,获取成功回调中的 ServerSession 返回给客户端。
nodejs 版本
Golang 版本
// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
const tencentcloud = require("tencentcloud-sdk-nodejs");

const CarClient = tencentcloud.car.v20220110.Client;

// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
const clientConfig = {
credential: {
secretId: "SecretId",
secretKey: "SecretKey",
},
region: "",
profile: {
httpProfile: {
endpoint: "car.tencentcloudapi.com",
},
},
};

const client = new CarClient(clientConfig);
const params = {
"UserId": "user-id",
"UserIp": "user-ip",
"ClientSession": "client-session"
};
client.CreateSession(params).then(
(data) => {
console.log(data);
},
(err) => {
console.error("error", err);
}
);
package main

import (
"fmt"

"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
car "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/car/v20220110"
)

func main() {
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
credential := common.NewCredential(
"SecretId",
"SecretKey",
)
// 实例化一个client选项,可选的,没有特殊需求可以跳过
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = "car.tencentcloudapi.com"
// 实例化要请求产品的client对象,clientProfile是可选的
client, _ := car.NewClient(credential, "", cpf)

// 实例化一个请求对象,每个接口都会对应一个request对象
request := car.NewCreateSessionRequest()
request.UserId = common.StringPtr("user-id")
request.UserIp = common.StringPtr("user-ip")
request.ClientSession = common.StringPtr("client-session")

// 返回的resp是一个CreateSessionResponse的实例,与请求对象对应
response, err := client.CreateSession(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
fmt.Printf("An API error has returned: %s", err)
return
}
if err != nil {
panic(err)
}
// 输出json格式的字符串回包
fmt.Printf("%s", response.ToJsonString())
}
完整代码可以参考后台 Demo

高级功能 - 排队功能

当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验具体操作请参见 排队功能

更多介绍

更多功能说明请查看 技术接入 文档 和 SDK 文档,如您有任何疑问或建议,或有特殊产品功能需求,请联系我们获得帮助。

并发包购买参考

对于类似全真互联未来会场的应用场景,一般在活动期间购买百-千路包天并发资源支持短期高并发用户需求,再购买数十路包月并发资源支持长期运营使用,即可满足业务需要,具体数量取决于实际业务需求。更多说明请参考 计费说明-根据业务场景选择最佳计费方式,如您有特殊计费需求,请联系我们。

体验小程序完整功能

除了接入应用云渲染产品,全真互联未来会场小程序还整合了腾讯云快直播、TRTC、IM、Avatar、数智人等产品和前沿技术,实现了虚拟形象、多人互动、直播、AI问答等多种玩法。手机微信搜索“腾讯全球数字生态大会-未来会场”小程序,即可体验完整功能,更多说明请参见走进未来——全真互联未来会场,今年的亮点都在这里!
说明:
建议您使用手机体验“腾讯全球数字生态大会-未来会场”小程序,效果更佳!