手机支持北斗卫星消息之后,企业 App 要重算的是字节预算
华为官宣畅享 100 系列三款机型(畅享 100、100 Pro、100 Pro Max)将于 10 月 28 日发布并已提前开启预订,顶配 Pro Max 为 6.84 英寸 1.5K、8000nits OLED,麒麟 8020 系列芯片,内置 8800mAh 电池(额定 8560mAh)支持 40W 快充,并支持北斗卫星通信,官方把主打卖点概括为”麒麟芯、防诈强、信号好、续航长”,最终定价要等发布会公布。本文不谈这些参数本身,也不猜发布结果。
要谈的是参数表里”支持北斗卫星通信”这一行落到企业 App 上会发生什么。对用户,它是无信号时能发出一条消息;对做业务系统的人,它是一条载荷极窄、往返慢、随时失败的上传通道。巡检终端在山区、井下、远海这些位置产生的数据要回传,走的就是这条口子,而口子窄到什么程度,决定了协议、状态机和整套离线架构怎么写。

一、先把”通道有多窄”换算成字节数
北斗三号公开的系统指标里,区域短报文单次最大报文长度为 14000 比特(折算约一千个汉字量级),全球短报文单次最大 560 比特(约四十个汉字的说法)。560 比特换成字节是 70 字节——这是整条报文的上限,不是业务字段的额度:位置信息、收发标识、协议开销都要从这几十字节里出。真正留给业务的字段,可能是几十字节甚至更少。终端与业务侧还会各自再加限制,系统标称上限不等于应用可用字节数,具体机型能给到多少要以厂商公布的能力为准。
| 通道 | 单条可用载荷 | 时延与频度特征 | 典型失败模式 | 该用来传什么 |
|---|---|---|---|---|
| 蜂窝 / Wi-Fi | MB 级 | 毫秒到百毫秒,随时可重试 | 弱网超时、DNS 失败 | 图片、音频、批量明细 |
| 区域短报文 | 数百到数千字节量级 | 秒级响应,但受发送频度约束 | 部分发送、回执缺失 | 状态快照、异常码、坐标 |
| 全球短报文 | 几十字节量级 | 更长且抖动大,频次受限 | 整条丢失、乱序 | 一条求救式的关键事实 |
结论直接决定设计:把 HTTP 加 JSON 的思路搬到窄通道上,第一条报文就发不出去。一个 UUID 字符串占 36 字节,一个 "status":"completed" 占 20 字节,再加上字段名和花括号,一个”看起来很简单”的状态上报就吃光了整条预算。
二、字段级压缩优先,压缩算法几乎没有位置
先把这个判断说清楚:在几十字节的输入上,通用压缩(DEFLATE、LZ4 一类)通常不会带来收益,反而可能因为头部开销和缺少重复串而膨胀。压缩算法解决的是”长文本里的冗余”,窄通道的问题是”字段本身太啰嗦”。顺序必须是先做字段级变换,实在省不下来再谈编码。
可复用的手段按收益排序:
- 枚举码表。把
"completed"、"abnormal"这类字符串换成 1 字节的状态码,码表双方各存一份。 - 位图合并。多个布尔项压进一个字节,每一位对应一个检查项,位序必须写进协议文档并冻结,改一位就等于改协议。
- 去掉自描述。JSON 的键名是最大浪费;改定长二进制或紧凑编码。注意紧凑编码里每个字段仍有类型与字段号开销,字段数量多的时候差异明显,不要以为换格式就自动省了。
- 换短码。设备号、人员号、点位号在报文里不要带原始 ID,全部换成本地码表索引,报文只带 1 到 2 字节的短索引。
- 差分与量化。坐标用相对基线的整型偏移(比如量化到 10 米精度),时间只报相对任务开始时刻的秒数,用 16 位就够覆盖几小时窗口。
- 幂等标识必须保留,但可以变短。去重不能省,只能把长 ID 换成短 ID。截断要算碰撞:按生日界估算,4 字节(32 位)截断标识在约一万条消息量级时碰撞概率就到百分之一这个档,按设备分片、控制保留窗口能压低它,但不能靠”应该撞不上”来定。
- 码表要带版本。用短码之后,报文里必须有一个版本字节,否则同一个
3在两个版本的表里指向两个不同点位。这类问题的表现是”数据都进来了,但内容错得离谱且没有任何报错”,比丢消息更危险。
一帧预算示例(字段划分是自造样例,不对应任何现网协议):
// 外勤状态快照,共 11 字节 |
同样的内容用 JSON 写出来超过 150 字节,压到 11 字节靠的不是算法,而是”每个字段只保留判读所需的最小信息”。
三、离线优先架构:事件日志、幂等上报、断点续传
窄通道不能当”慢一点的网”用,它需要把上传变成一种可中断、可重放的过程。可用的结构是三层。
第一层是本地事件日志。界面上的每一次操作只写日志,不直接调网络:追加写,每条带单调序号、设备本地时间、会话标识。写日志是唯一必须成功的动作,其余都允许失败。这样即使发送过程被进程杀死、断电、用户强行退出,数据也还在原地。
第二层是幂等上报。服务端按 (设备短码, 序号) 去重,客户端收到确认后才推进游标。未确认的区间可以任意次重发,服务端不会因此重复计数。幂等键要在协议里固定下来,不能靠时间戳充当——设备时钟不可信,时间可能漂移,也可能被用户改。收端以服务端接收时间为准,设备只带相对时间和序号,顺序由序号决定。
第三层是断点续传。一条逻辑消息切成若干片,每片带消息标识、片号、总片数与校验。窄通道下发送顺序不保证、回执也不保证,收端按片号重排,缺片通过一次回补请求重发那一片。还要有整条的过期策略(TTL):一条半消息挂了两小时之后再补齐,拼出来的内容可能已经不是现场当时的事实了,此时应当标记为”残缺”而不是拼合。
这套结构还有一个隐性收益:蜂窝恢复后的批量回补,和窄通道上传,共用同一份事件日志。业务代码只依赖一个”通道抽象 + 每条通道的字节预算”接口,不为卫星单独写一套上报逻辑。凡是把两条路径写成两套代码的,后面一定会出现”卫星传上来的和 4G 传上来的字段含义不一致”。
四、状态机要能降级完成:必回、可延后、只留本地
取舍表要落到字段上,否则一线开发只能凭感觉。巡检任务这个场景可以这样分档:
| 档位 | 字段 | 理由 |
|---|---|---|
| 必回 | 任务短码、点位短码、状态枚举、异常码、量化位置、时间偏移、序号 | 缺任何一项,调度侧就无法判断”人在哪、做没做、要不要支援” |
| 可延后 | 现场照片、录音、长备注文本、完整 ID 原文、明细读数 | 有蜂窝时回补;窄通道带上会挤掉必回项 |
| 只留本地 | 人员生物特征、内部敏感配置、临时诊断日志、原始传感器流 | 不该进窄通道:链路可被第三方看到,且预算不该花在这上面 |
状态迁移本身要按”每条报文可独立读懂”来设计。从”已到场”到”检查项完成”到”需要支援”,每一步都用一个完整状态快照表达,而不是只发一个增量事件。两种取舍要摊开讲:
- 快照式:每条报文都携带完整状态,字节数偏多,但任何一条单独到达都能被理解,抗丢包。窄通道选它。
- 增量式:只报变化,省字节,但一条丢失会让后续全部错位,需要额外的对齐与重同步机制。蜂窝回补明细时选它。
组合方式是”窄通道走快照,恢复后走增量补明细”,序号用来丢弃过期快照,避免旧快照晚到覆盖新状态。
还要提前定重试预算和人工兜底:连续若干次未送达,界面必须给出可读提示(哪条数据没出去、多大、什么时候会再试),而不是转圈;同时提供本地导出通道。应急场景里最容易出的事故不是信号差,是”用户以为已经报上去了”。
五、测试要真的把带宽压窄,而不是打开飞行模式
只测”无网络时界面不崩”是不够的,那连协议的一半都没碰到。可执行的做法是搭一个窄通道模拟器,把真实约束逐项还原:单次发送字节上限设到几十、发送频度限成每分钟一条、丢包率打到两位数百分比、允许乱序、回执延迟大且抖动、半双工(发送期间不能收)。在这套环境下跑下面这些用例,每条都要有明确判据:
- 业务消息超过单帧预算时能正确分片,收端重组后与原始内容逐字节一致;
- 中途丢掉一片,重传后服务端不产生重复记录,也不出现同一消息的两个版本;
- 应用被杀、设备重启之后,游标与未确认区间不丢不重,日志文件不出现撕裂记录;
- 码表版本不一致时服务端明确拒绝并报出可读错误,绝不静默错映射到另一个点位;
- 设备时钟偏差推到几十分钟,事件顺序判定仍然只依赖序号,报表时序不错乱;
- 连续多次发送失败后,界面提示具体可执行动作,且本地数据仍可完整导出;
- 窄通道送达后蜂窝恢复并回补明细,两侧对账既不重复也不缺项;
- 乱序到达的旧快照被序号丢弃,最终状态与现场实际操作顺序一致。
压测的判据不要写成”能收到”,要写成”收到的内容可判读、可去重、可对账”。协议设计里的所有余量,最后都会在丢包率两位数的环境下暴露。
六、洹拓视角:中间那段工作叫协议和产品约束
硬件宣传里的”卫星消息”要变成业务可用通道,中间隔着三类决定,我们接手这类需求时按顺序确认。
- 需求文档要写”窄通道下的最小可读信息”,而不是写”支持离线上传”。前者能被拆成字段表和字节预算,后者只能被理解成”多发几次”。
- 把字节预算当成和界面规范同级的交付物。每个字段占几位、为什么是这个位数、超预算时丢谁,都要写在协议文档里并版本化。协议一旦发出去,改一位就是灰度问题。
- 分级通道共用一份事件日志,业务侧只依赖”通道 + 预算”这一个抽象。同时要诚实地把取舍公开:哪些信息在窄通道下传不回来,让使用方知道边界,比在页面上写”支持卫星通信”更有价值。
顺带一条边界:不要把”支持卫星消息”宣传成”数据都能传回来”。通道窄意味着一定有人在被延后的档位里等照片,这个预期差会在应急现场变成实际损失。