- 示例工程
- 小程序
- 前端
【免费下载链接】miniprogram-demo
微信小程序组件 / API / 云开发示例
本篇技术指南以微信小程序开源示例仓库 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 的核心执行逻辑为:
- 解析配置:读取
--config指向的svrkit.config.js,将其中每个模块项的proto字段解析为绝对路径(config.map(c => path.resolve(path.dirname(configPath), c.proto))); - 生成静态模块:调用
protobufjs的pbjsCLI,以static-module模式生成可独立运行的 JS 静态模块,输出为svrkit-utils.static.js:const pbjsArgs = ['-t', 'static-module', '-w', 'commonjs', '-l', 'eslint-disable', '-o', staticModuleFilePath, ...protos] - 生成 JSON descriptors:再次调用
pbjs以json模式输出协议描述,得到svrkit-utils.static.json(其中以nested结构记录所有枚举、消息字段及编号,供参数合法性校验使用); - 拼接模板产出主文件:读取模板 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_Default | 0 | 默认状态 |
| ARModel_Status_Init | 1 | 初始化中 |
| ARModel_Status_Sparse_Finished | 2 | 稀疏点云重建完成 |
| ARModel_Status_3d_Finished | 3 | 3D 模型重建完成 |
| ARModel_Status_Object_Finished | 4 | 目标物体重建完成 |
| ARModel_Status_Marker_Finished | 5 | Marker 模型重建完成 |
| ARModel_Status_Fail | 100 | 生成失败 |
enARAlgorithmType(算法类型):
| 枚举值 | 数值 | 含义 |
|---|---|---|
| Algorithm_Type_3D_Object | 1 | 3D 物体识别算法 |
| Algorithm_Type_3D_Marker | 2 | 3D Marker 识别算法 |
enARModelType(模型类型):
| 枚举值 | 数值 | 含义 |
|---|---|---|
| ARModel_Type_Sparse | 1 | 稀疏点云 |
| ARModel_Type_3D | 2 | 3D 模型 |
| ARModel_Type_Marker | 3 | Marker 模型 |
模型元数据与存储映射
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的字段及约束:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| bizuin | uint32 | - | 业务号 |
| name | string | - | 模型名称 |
| buffer | bytes | - | 原始文件数据 |
| url | string | - | 原始文件地址(二选一提交) |
| algo_type | enARAlgorithmType | - | 算法类型:1=3D Object,2=3D Marker |
| lod | uint32 | 0 | 重建模型精度,最高精度为 0,取 1/2/3 时精度依次下降 |
| getmesh | bool | false | 是否返回 obj 二进制网格 |
| gettexture | bool | false | 是否返回纹理二进制 |
GenerateARModelResp返回:url、host、cosid,以及回显的lod、getmesh、gettexture。
GetARModel:获取重建产物
GetARModelReq的字段及约束:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| bizuin | uint32 | - | 业务号 |
| cosid | string | - | 模型 cosid |
| model_type | uint32 | - | 1=稀疏点云,2=3D 模型,3=Marker 模型 |
| need_data | uint32 | 1 | 0=不需要数据,1=需要数据 |
| use_intranet | uint32 | 0 | 仅在 need_data 为 0 时生效:0=生成外网链接,1=内网链接 |
| expire_time | uint32 | - | 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": ... } }几个关键实现细节:
- bizuin 自动注入:云函数通过
cloud.getWXContext().APPUIN获取当前调用方业务号,小程序端无需(也不应)自行传入,避免越权; - 类型分发:以
event.type区分GenerateARModel与GetARModel两个动作,参数直接透传event中的对应字段; - 超时控制:两次调用均设置
timeout: 30000,适配三维重建这种耗时的后台任务; 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 的子包)结合仓库文件可以补充说明各步骤的具体含义:
- 安装依赖:在 ARDemo 目录执行依赖安装,使
wx-server-sdk、@tencent/cloud-functions-tools等(见 package.json)进入本地node_modules,保证本地生成的调用代码与运行环境依赖完整; - 切换环境:在微信开发者工具中将云函数环境切换为 test 环境,对应 proto 中
option(mmbizintpkv.KvTableTestID) = 916使用的测试 KV 表 ID; - 上传所有文件:在开发者工具中对 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 / 云开发示例
相关推荐
微信小程序全栈开发实战:基于 agency-agents-zh「微信小程序开发者」智能体的架构设计、微信支付与云开发全链路指南
微信小程序全栈开发实战:基于 agency agents zh「微信小程序开发者」智能体的架构设计、微信支付与云开发全链路指南 本指南以 agency agen
人工智能AI 技能提示工程微信小程序组件/API/云开发示例:微前端架构与小程序集成完整指南
微信小程序组件/API/云开发示例:微前端架构与小程序集成完整指南 微信小程序组件、API和云开发示例为开发者提供了完整的小程序开发解决方案。这个开源项目展示了
示例工程小程序前端如何快速构建生活服务小程序:微信小程序组件与云开发完整指南
如何快速构建生活服务小程序:微信小程序组件与云开发完整指南 微信小程序凭借其无需下载安装、即用即走的特性,已成为生活服务类应用的理想载体。本指南将带你通过微信官
示例工程小程序前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考