☰
微信小程序云开发 AR 三维识别与重建云服务 ARDemo 实战指南:proto 驱动 svrkit 协议链路全解析
2026/10/15 16:00:39 网站建设 项目流程
  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

本篇技术指南以微信小程序开源示例仓库 miniprogram-demo 中的 cloudfunctions/ARDemo 云函数为核心,系统讲解如何基于 protobuf 协议文件(proto)驱动 svrkit 调用链,完成三维识别与重建云服务的接口定义、代码生成、云函数编写与部署更新。读完本文,你将掌握npm run svrkit背后完整的生成原理、ARDemo 提供的模型生成/查询协议字段含义,以及小程序端调用该云函数的完整实战链路。

ARDemo 云函数是什么

ARDemo 是 miniprogram-demo 仓库中面向「三维识别与重建」场景的云函数示例。它并不是一个自研算法的实现,而是作为微信小程序云开发环境与后台 svrkit 服务之间的协议桥:云函数接收小程序端请求,将参数按 protobuf 协议编码,通过wx-server-sdk提供的callWXSvrkit能力转发到后台「Mmbizwxaintpar」服务,从而完成 AR 模型的提交生成与结果获取。

从仓库目录结构看,ARDemo 云函数包含以下关键组成:

  • 入口文件 index.js:云函数入口,负责事件分发与 svrkit 调用;
  • proto 协议文件:定义 AR 模型相关的枚举、消息与接口契约;
  • svrkit.config.js:声明 serviceName、magic、cmdid 及请求/响应消息映射;
  • svrkit-utils.js:由 CLI 工具生成的调用工具(含.static.js、.static.json两个附属产物);
  • cloud-functions-tools:内置的@tencent/cloud-functions-tools生成器源码与测试样例;
  • wx-server-sdk-wxg-service:云开发 SDK 的内部服务插件,注册后云函数才具备callWXSvrkit能力。

整个链路可以概括为:proto 定义契约 → CLI 生成调用代码 → 云函数按类型分发 →callWXSvrkit转发后台 → 返回结果给小程序端。

proto 更新:从协议变更到代码再生成

ARDemo 的协议以 protobuf 为准,后台接口的任何变更都通过更新 proto 文件 并重新生成 JS 调用代码来同步。原文档给出的流程分两步。

第一步:安装依赖

在 ARDemo 目录下安装腾讯内部 npm 包管理工具(tnpm)对应的生成器依赖:

// ARDemo 目录下 tnpm install --save-dev @tencent/cloud-functions-tools@latest

该依赖在 package.json 中被声明为:

"devDependencies": { "@tencent/cloud-functions-tools": "^1.7.0" }

工具包通过bin字段对外暴露svrkit-utils命令行(见 cloud-functions-tools/package.json):

"bin": { "svrkit-utils": "bin/svrkit-utils" }

第二步:基于 proto 文件生成脚本逻辑

// ARDemo 目录下 npm run svrkit

该命令对应的脚本定义在 package.json 中:

"scripts": { "svrkit": "svrkit-utils --config ./svrkit.config.js --output ./svrkit-utils.js" }

即:以svrkit.config.js为配置入口,将生成结果输出到svrkit-utils.js。每次修改 proto 后都需重新执行一次该命令,让协议字段、枚举值与云函数侧保持严格一致。

npm run svrkit 背后发生了什么

要理解这条命令,需要直接阅读生成器实现 cloud-functions-tools/cli/svrkit-utils.js。该 CLI 的核心执行逻辑为:

  1. 解析配置:读取--config指向的svrkit.config.js,将其中每个模块项的proto字段解析为绝对路径(config.map(c => path.resolve(path.dirname(configPath), c.proto)));
  2. 生成静态模块:调用protobufjs的pbjsCLI,以static-module模式生成可独立运行的 JS 静态模块,输出为svrkit-utils.static.js:
    const pbjsArgs = ['-t', 'static-module', '-w', 'commonjs', '-l', 'eslint-disable', '-o', staticModuleFilePath, ...protos]
  3. 生成 JSON descriptors:再次调用pbjs以json模式输出协议描述,得到svrkit-utils.static.json(其中以nested结构记录所有枚举、消息字段及编号,供参数合法性校验使用);
  4. 拼接模板产出主文件:读取模板 svrkit-utils-template.js,与配置引用、静态模块、JSON 描述拼接后写入svrkit-utils.js:
    const output = ` const config = require('${svrkitConfigRelativePath}') const proto = require('./${staticModuleFileName}') const protoJSON = require('./${staticJsonFileName}') ${protoUtils} `

最终生成的 svrkit-utils.js 对外暴露两个方法:

  • generate(options):面向 svrkit 协议,入参为{ serviceName, funcName, data },输出{ data, reqProto, resProto, decode };
  • generateV2(options):面向新协议,入参为{ apiName, data },输出结构更精简。

以generate为例,其内部完成三件关键工作:

(1)配置查找与校验:按serviceName在svrkit.config.js中定位模块,按funcName定位接口,找不到即抛出service not found/function not found;

(2)proto 校验:通过reqProto.verify(data)校验字段类型,并借助 JSON descriptors 检查传入的每个 key 是否属于 proto 定义的合法字段,非法 key 会抛出:

'xxx' doesn't exist in 'GenerateARModelReq' proto, valid keys are ...

这一机制保证了云函数侧拼装的参数与后台契约完全一致,避免协议漂移导致的隐性错误;

(3)构造调用负载:将参数用reqProto.encode(data).finish()编码为reqBodyBuffer,连同serviceName、funcName、magic、cmdid、existResp一起打包,供 SDK 转发:

return { data: { serviceName, funcName, magic: serviceConfig.magic, cmdid: serviceConfig.functions[funcName].cmdid, existResp: Boolean(resProto), reqBodyBuffer: reqProto.encode(data).finish(), }, reqProto, resProto, decode: buf => resProto && resProto.decode(buf) }

仓库 cloud-functions-tools/test/svrkit-utils/example 目录下保留了生成器的完整测试样例(demo.proto、svrkit.config.js、生成的svrkit-utils.js等),可作为理解生成产物形态的参考。

协议文件详解:三维识别与重建的接口契约

proto 文件 是 ARDemo 的核心契约,定义了 3 个枚举与 7 个消息。

枚举定义

enARModelStatus(模型状态机):

枚举值数值含义
ARModel_Status_Default0默认状态
ARModel_Status_Init1初始化中
ARModel_Status_Sparse_Finished2稀疏点云重建完成
ARModel_Status_3d_Finished33D 模型重建完成
ARModel_Status_Object_Finished4目标物体重建完成
ARModel_Status_Marker_Finished5Marker 模型重建完成
ARModel_Status_Fail100生成失败

enARAlgorithmType(算法类型):

枚举值数值含义
Algorithm_Type_3D_Object13D 物体识别算法
Algorithm_Type_3D_Marker23D Marker 识别算法

enARModelType(模型类型):

枚举值数值含义
ARModel_Type_Sparse1稀疏点云
ARModel_Type_3D23D 模型
ARModel_Type_Marker3Marker 模型

模型元数据与存储映射

ARModel描述一条模型记录,其option(mmbizintpkv.KvTableTestID) = 916声明了测试环境下的 KV 存储表 ID,字段包括:cosid(原始文件 cosid)、bizuin(业务号)、name(原始文件名)、upload_time、model_status、algo_type以及嵌套的ModelCos。

ModelCos / ModelCosId用于记录模型生成过程中各类型产物的 cosid 映射:每个ModelCosId包含model_type、model_cosid与errmsg(某类型生成失败时的错误信息),整体以model_list数组形式挂在ModelCos下。

GenerateARModel:提交生成请求

GenerateARModelReq的字段及约束:

字段类型默认值说明
bizuinuint32-业务号
namestring-模型名称
bufferbytes-原始文件数据
urlstring-原始文件地址(二选一提交)
algo_typeenARAlgorithmType-算法类型:1=3D Object,2=3D Marker
loduint320重建模型精度,最高精度为 0,取 1/2/3 时精度依次下降
getmeshboolfalse是否返回 obj 二进制网格
gettextureboolfalse是否返回纹理二进制

GenerateARModelResp返回:url、host、cosid,以及回显的lod、getmesh、gettexture。

GetARModel:获取重建产物

GetARModelReq的字段及约束:

字段类型默认值说明
bizuinuint32-业务号
cosidstring-模型 cosid
model_typeuint32-1=稀疏点云,2=3D 模型,3=Marker 模型
need_datauint3210=不需要数据,1=需要数据
use_intranetuint320仅在 need_data 为 0 时生效:0=生成外网链接,1=内网链接
expire_timeuint32-URL 过期时间,默认 5 分钟,单位秒,最长 1800

GetARModelResp包含model_data、url、host、errMsg、expire_time与status。其中status取值:0=生成中,1=生成成功,2=过期,3=生成失败。

ARModelData定义了产物的负载结构:mesh_model(文本点面信息)、texture_model(PNG 纹理图像)、preview(预览图)、mesh_blob(obj 二进制,getmesh=true时返回)、texture_blob(纹理二进制,gettexture=true时返回)。

GetARModelList:列表查询(已废弃)

GetARModelListReq / GetARModelListResp提供按bizuin、model_status、algo_type、时间区间与分页参数(offset/limit)查询模型列表的能力。需要特别注意的是,在云函数 index.js 中该接口已被注释并标注「GetARModelList 废弃,完全依赖本地缓存」——当前实现不再透传该接口,模型列表由小程序端本地缓存维护。

svrkit.config.js:模块与接口的注册表

svrkit.config.js 导出一个配置数组,每个元素对应一个后台服务模块:

module.exports = [ { proto: './proto/mmbizwxaintparDemo.proto', // proto 文件相对路径 serviceName: 'Mmbizwxaintpar', // 后台 service name magic: 11081, // 模块 magic 数字 functions: { GenerateARModel: { cmdid: 1, req: 'GenerateARModelReq', res: 'GenerateARModelResp' }, GetARModelList: { cmdid: 3, req: 'GetARModelListReq', res: 'GetARModelListResp' }, GetARModel: { cmdid: 4, req: 'GetARModelReq', res: 'GetARModelResp' } } } ]

各配置项的职责:

  • proto:本模块对应的 proto 文件路径,生成器据此定位协议;
  • serviceName:后台服务的标识,云函数调用时需与后台部署一致;
  • magic:模块数字签名,用于路由校验;
  • functions:模块暴露的接口集合,每个接口包含cmdid(接口号)、req/res(对应的 protobuf message 名,必须在 proto 文件中定义)。

注意GetARModelList仍保留在配置中(cmdid=3),但云函数入口已不再调用它,仅保留定义以便协议层面对齐。

云函数入口:事件分发与 svrkit 转发

cloudfunctions/ARDemo/index.js 是完整的云函数入口,其工作流如下:

const cloud = require('wx-server-sdk') const wxgService = require('./wx-server-sdk-wxg-service') const svrkitUtils = require('./svrkit-utils.js') cloud.registerService(wxgService) cloud.init() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const bizuin = wxContext.APPUIN switch (event.type) { case 'GenerateARModel': return await cloud.callWXSvrkit({ pbInstance: svrkitUtils.generate({ serviceName: 'Mmbizwxaintpar', funcName: 'GenerateARModel', data: { bizuin, name: event.name, url: event.url, algoType: event.algoType, getmesh: event.getMesh, gettexture: event.getTexture }, }), timeout: 30000, }) case 'GetARModel': return await cloud.callWXSvrkit({ pbInstance: svrkitUtils.generate({ serviceName: 'Mmbizwxaintpar', funcName: 'GetARModel', data: { bizuin, cosid: event.cosid, modelType: event.modelType, needData: event.needData, useIntranet: event.useIntranet, expireTime: event.expireTime }, }), timeout: 30000, }) // GetARModelList 废弃,完全依赖本地缓存 // case "GetARModelList": ... } }

几个关键实现细节:

  1. bizuin 自动注入:云函数通过cloud.getWXContext().APPUIN获取当前调用方业务号,小程序端无需(也不应)自行传入,避免越权;
  2. 类型分发:以event.type区分GenerateARModel与GetARModel两个动作,参数直接透传event中的对应字段;
  3. 超时控制:两次调用均设置timeout: 30000,适配三维重建这种耗时的后台任务;
  4. wx-server-sdk-wxg-service的桥接作用:cloud.registerService(wxgService)注册内部服务插件。从 wx-server-sdk-wxg-service/index.js 打包产物可见,callWXSvrkit底层通过/inner/svrkitclientcall接口上报req_body_buffer(base64)、service_name、func_name、magic、cmdid等字段,并将响应的resp_body_buffer反解为respBody对象返回给云函数调用方,最终透传给小程序端。

服务更新:部署与上传步骤

原文档给出的服务更新流程如下:

1. 安装 ARDemo 下本地 npm 依赖 2. 云函数环境切为 test 环境 3. ARDemo 右键上传所有文件(由于有 @tencent 的子包)

结合仓库文件可以补充说明各步骤的具体含义:

  1. 安装依赖:在 ARDemo 目录执行依赖安装,使wx-server-sdk、@tencent/cloud-functions-tools等(见 package.json)进入本地node_modules,保证本地生成的调用代码与运行环境依赖完整;
  2. 切换环境:在微信开发者工具中将云函数环境切换为 test 环境,对应 proto 中option(mmbizintpkv.KvTableTestID) = 916使用的测试 KV 表 ID;
  3. 上传所有文件:在开发者工具中对 ARDemo 目录「右键 → 上传并部署:云端安装依赖(不上传 node_modules)」。由于项目包含@tencent前缀的内部子包(wx-server-sdk-wxg-service、cloud-functions-tools等),必须选择上传所有文件,确保这些子包连同生成代码一并部署到云端,否则运行时require会失败。

注意:云函数的部署配置(如开放接口权限)位于 config.json,其中permissions.openapi当前为空数组,表示该云函数未申请额外的微信开放接口权限——它只通过 svrkit 内部协议访问后台服务,不走开放 API。

小程序端调用链示例

ARDemo 云函数由小程序端 AR 页面通过wx.cloud.callFunction触发。以 arModelComponent.js 为例:

提交模型生成:

wx.cloud.callFunction({ name: 'ARDemo', config: { env: this.data.envId }, data: { type: 'GenerateARModel', name: this.data.modelName, url, algoType: 2, // Algorithm_Type_3D_Marker getMesh: true, getTexture: true } }).then((resp) => { /* 生成成功处理 */ })

基于缓存 cosid 获取模型:

wx.cloud.callFunction({ name: 'ARDemo', config: { env: this.data.envId }, data: { type: 'GetARModel', cosid, modelType: 3, // Marker 模型 needData: 0, // 不需要数据,走 URL 直链 useIntranet: 0, // 生成外网链接 expireTime: 1200 // 过期时间 1200 秒(≤1800 上限) } }).then(resp => { const modelStatus = resp.result.respBody.status // 0 生成中 / 1 生成成功 / 2 过期 / 3 生成失败 })

可以清晰地看到小程序端参数与 proto 字段的映射关系:type对应云函数入口的event.type分发;algoType、getMesh、getTexture对应GenerateARModelReq;cosid、modelType、needData、useIntranet、expireTime对应GetARModelReq。而「列表完全依赖本地缓存」的设计,也解释了为何GetARModelList在云函数中被废弃——小程序的modelInfos本地缓存承担了列表查询职责,云函数仅保留生成与获取两个热路径接口。

总结

ARDemo 展示了微信小程序云开发中一种典型的「后台 svrkit 服务接入」范式:以 proto 文件为唯一契约源,通过@tencent/cloud-functions-tools的svrkit-utilsCLI 一键生成静态模块、JSON 描述与调用工具,云函数入口只需做事件分发与参数透传,即可通过callWXSvrkit完成与后台服务的协议级交互。整套链路中,proto 文件、svrkit.config.js、svrkit-utils.js 与 index.js 四者构成闭环,任何协议变更只需「改 proto →npm run svrkit→ 上传部署」,为三维识别与重建类 AR 能力的小程序集成提供了可复制的工程样板。

  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询