最近帮朋友调试一款智能手环的配套APP,发现不少开发者只盯着手机端怎么连蓝牙、怎么收数据,却没想清楚——服务器那边到底该接什么、存什么、怎么响应。
别把BLE当普通HTTP接口用
低功耗蓝牙(BLE)本身不走网络,APP和设备之间是点对点短距通信。但用户一打开APP,常要同步历史步数、设置闹钟、升级固件……这些动作背后,其实都得靠服务器撑着。
比如手环每天凌晨自动上传前24小时心率采样点,APP在本地打包成JSON,再POST到 /api/v1/health/upload。这时候服务器得能接住这批带设备ID、时间戳、加密签名的数据,还得校验是否重复提交、是否超出单次最大条数限制。
设备标识和会话管理不能省
BLE设备没有IP,靠MAC地址或厂商自定义的UUID识别。APP首次配网时,得把设备唯一标识、用户ID、绑定时间一起发到服务端:
{"device_id": "A1:B2:C3:D4:E5:F6", "user_id": 8827, "bind_time": "2024-05-12T09:33:11Z"}服务器收到后,生成一个短期有效的token(比如JWT),返回给APP。之后每次上报数据,都要带上这个token——不是为了防黑客,而是防止同一台设备被多个账号反复绑定,或者旧APP进程偷偷续传老数据。
固件升级得有状态机
BLE OTA升级最怕断连重试乱套。APP请求升级包时,服务器不能直接甩个URL完事。建议用三步走:
1. APP先GET /api/v1/firmware/check?device_id=A1:B2:C3:D4:E5:F6¤t_ver=1.2.0;
2. 服务器查数据库,返回是否需升级、新版本号、分片大小、校验码;
3. APP按分片GET下载,每片传完发一次确认,服务器记录当前进度。
这样哪怕用户中途切后台、蓝牙断开,回来还能从断点继续,不用重头下2MB固件。
别忘了心跳和离线兜底
手环不会主动连服务器,但APP可以。建议APP每4小时静默上报一次设备在线状态(哪怕就一个字段:{"status": "online"})。服务器存进Redis,过期时间设为6小时。运维看板上就能实时刷出“已离线超6小时”的设备列表,方便批量排查电池耗尽或固件卡死的问题。
顺带一提:这类轻量请求别塞进主业务库,用Redis+定时清理更稳。我们之前把所有设备心跳全写MySQL,结果某天慢查询拖垮了订单接口——教训挺实在。