6.0 KiB
6.0 KiB
原生与 H5 Bridge 协议草案
本文档定义当前项目中 原生小程序 与 H5 定制内容页 之间的基础通信协议。
目标:
- 让 H5 能获取当前游戏上下文
- 让 H5 能请求原生能力
- 让原生能接收 H5 的结果回传
- 保持协议简单、稳定、可版本化
- 为后续拍照、录音、小游戏、结果页等扩展留出空间
0. 当前适用前提
本规范当前属于:
- 协议与实现预留
- 容器与回退机制先行
最近排查已经确认,当前最初使用的是个人主体小程序。
在这个前提下,web-view 能力本身可能受限。
因此:
- Bridge 规范仍然应该先定义
- 容器页与回退机制也应该先实现
- 但在企业主体审核通过前,不应把 H5 接入是否成功完全归因于 bridge 代码本身
详细说明见:
1. 协议原则
原则 1:Bridge 要版本化
建议先固定:
content-v1result-v1
后续升级时:
- 新增
content-v2 - 新增
result-v2
不要直接改旧协议。
原则 2:请求能力最小化
先只开放真正需要的能力,不要一开始做成“大而全总线”。
原则 3:原生控制核心状态
Bridge 只能做:
- 展示
- 上报
- 请求能力
不能让 H5 直接改比赛核心状态。
原则 4:消息必须可回执
每个请求都应有明确成功/失败返回,不允许 H5 靠超时猜测。
2. 通道模型
建议统一按“请求 / 响应 / 事件”三类消息组织:
requestH5 请求原生能力response原生返回能力执行结果event原生主动推送状态变化
推荐消息外壳:
{
"id": "req-001",
"channel": "request",
"type": "getGameContext",
"payload": {}
}
响应:
{
"id": "req-001",
"channel": "response",
"type": "getGameContext",
"ok": true,
"payload": {}
}
3. 原生注入给 H5 的基础上下文
建议至少包含:
{
"bridgeVersion": "content-v1",
"eventId": "sample-score-o-001",
"mode": "score-o",
"sessionId": "session-001",
"sessionStatus": "running",
"controlId": "control-3",
"controlKind": "control",
"title": "湖边步道",
"body": "这里适合短暂停留观察周边地形。",
"theme": "default-race"
}
对于结果页,可扩展为:
{
"bridgeVersion": "result-v1",
"eventId": "sample-score-o-001",
"mode": "score-o",
"sessionId": "session-001",
"summary": {
"title": "比赛结束",
"heroValue": "120",
"rows": []
}
}
4. H5 -> 原生:第一阶段推荐动作
建议第一阶段只支持这几个:
close
作用:
- 关闭当前 H5 页面
示例:
{
"id": "req-001",
"channel": "request",
"type": "close",
"payload": {}
}
getGameContext
作用:
- 让 H5 主动获取最新上下文
takePhoto
作用:
- 请求原生拍照
recordAudio
作用:
- 请求原生录音
submitResult
作用:
- 把 H5 内的任务结果、表单或作品结果提交回原生
示例:
{
"id": "req-002",
"channel": "request",
"type": "submitResult",
"payload": {
"taskId": "photo-task-1",
"status": "completed",
"assetId": "img-001"
}
}
5. 建议第二阶段可扩展动作
等第一阶段跑稳后,再逐步加入:
uploadImageuploadAudiogetLocationopenMiniGamesubmitFormsharerestartSession
这些先不要第一阶段全开。
6. 原生 -> H5:统一返回结构
建议统一返回:
{
"id": "req-002",
"channel": "response",
"type": "takePhoto",
"ok": true,
"payload": {
"assetId": "img-001",
"url": "https://example.com/assets/img-001.jpg"
}
}
失败时:
{
"id": "req-002",
"channel": "response",
"type": "takePhoto",
"ok": false,
"error": {
"code": "USER_CANCELLED",
"message": "用户取消拍照"
}
}
7. 原生 -> H5:推荐事件
原生可按需主动推送轻量事件:
contextUpdatedsessionFinishedsessionExitednetworkChanged
但第一阶段要克制,避免高频推送。
不建议第一阶段主动高频推:
- GPS 实时位置流
- 指北针实时角度
- HUD 高频数字
这些不适合让 H5 主导。
8. 错误码建议
建议第一阶段统一几类错误:
USER_CANCELLEDPERMISSION_DENIEDNETWORK_ERRORUNSUPPORTED_ACTIONBRIDGE_NOT_READYINTERNAL_ERROR
这样 H5 侧更容易统一处理。
9. 安全与边界
9.1 H5 不直接改核心比赛状态
H5 不能直接决定:
- 是否打点成功
- 是否跳点成功
- 是否比赛结束
9.2 H5 只能请求能力
原生决定是否执行:
- 拍照
- 录音
- 上传
- 页面关闭
9.3 Bridge 能力按页面类型开放
例如:
- 内容页开放
takePhoto - 结果页不一定开放
后续可做按 bridgeVersion 或 pageType 的能力白名单。
10. 第一阶段推荐支持范围
建议第一阶段只正式支持:
closegetGameContexttakePhotorecordAudiosubmitResult
这样足够承接:
- 文创详情
- 拍照任务
- 语音留言
- 结果页回传动作
11. 不建议第一阶段支持的内容
先不要一上来开放:
- 任意写比赛状态
- 任意切换玩法
- 任意修改地图行为
- 任意控制打点
- 高频实时 telemetry 推送
这些都属于核心状态,应该继续由原生掌控。
12. 当前建议实施顺序
- 先实现一个通用 H5 容器页
- 先跑通
content-v1 - 先支持 5 个最小动作
- 再跑通一个简单结果页
- 最后再扩桥接能力
13. 当前建议结论
Bridge 的第一阶段目标,不是做成万能总线,而是:
稳定承接定制内容页与结果页的最小需求。
先把:
- 关闭
- 获取上下文
- 拍照
- 录音
- 结果提交
这 5 条做稳,就足够支撑第一波客户定制需求。