自动回连机制
自动回连(Auto Reconnect)是杰理微信小程序 OTA SDK(jl_ota_2.1.1)中为单备份 OTA 设计的关键机制:当设备在升级过程中重启并重新进入可连接状态时,SDK 通过 onNeedReconnect 回调通知上层,并(可选地)在内部自动完成 BLE 重连,从而让升级流程无感续传,显著提升用户体验。
Purpose and Scope
本页面向自动回连机制这一主题,覆盖:
- 自动回连的触发条件与使用场景(单备份 OTA)
- 回连相关的核心接口与数据结构(
OTAConfig、ReConnectMsg、OnUpgradeCallback.onNeedReconnect、OTAWrapperOption.isInnerReconnect) - SDK 内部回连实现机制(
OTAImpl中的回连定时器、RECONNECT_DEVICE_DELAY、超时控制) - 新旧两种回连方式(传统广播搜索 vs 基于 BLE MAC 的新回连方式)
- 上层(小程序业务层)集成自动回连的完整步骤与代码示例
- 回连相关的错误码、失败模式与边界情况
以下内容不属于本页范围,由其他目录页覆盖:
- 蓝牙扫描/连接/收发的通用能力(
OTAWrapperOption的sanDevice、connectDevice等基础蓝牙操作) - 认证(Auth)流程本身
- 双备份 OTA 的取消逻辑(
cancelOTA仅对双备份方案有效) - RCSP 协议与
jl_rcsp_ota的具体协议实现
Overview
为什么需要自动回连
在单备份 OTA(single-backup OTA)方案中,升级流程通常包含两个阶段:
- 传输 BootLoader / 校验文件(
UPGRADE_TYPE_CHECK_FILE) - 传输固件内容(
UPGRADE_TYPE_FIRMWARE)
其中"传输 BootLoader"阶段完成后,设备需要重启并进入升级模式,此时原 BLE 连接必然断开。若没有自动回连机制,上层必须手动重新扫描、重新连接设备,用户会看到"连接断开"的体验,升级也可能因错过设备重启完成的时间窗口而失败。
自动回连机制正是为了解决这个问题:SDK 在检测到设备需要重启回连时,通过 onNeedReconnect(reConnectMsg) 回调告知上层,上层只需"仅连接通讯通道(BLE 或 SPP)",随后 SDK 内部继续推进 OTA 流程。
两种回连方式
| 方式 | 触发配置 | 机制 | 适用版本 |
|---|---|---|---|
| 传统回连 | 默认行为 | 上层重新扫描广播并连接设备 | 全版本 |
| 新回连方式(New Reboot Way) | otaConfig.isSupportNewRebootWay = true | 基于 RCSP 协议上报的 deviceBleMac 直接定向连接,无需重新扫描;支持设备侧新回连广播 isSupportNewReconnectADV | SDK 2.1.x 起(V2.1.1 修复 iOS16 下新回连搜不到设备问题) |
新回连方式的优势在于:不必依赖全量广播扫描,而是利用 RCSP 通讯中获取到的设备 BLE MAC 地址(ReConnectMsg.deviceBleMac)做定向重连,更快速、更可靠。
Architecture
下图展示了自动回连机制在整个 OTA 系统中的位置与组件关系:
flowchart TD
subgraph sg_Business["小程序业务层(上层)"]
BLE["蓝牙管理实例<br/>(扫描/连接/断开/收发)"]
OTAWrapper["OTAWrapper"]
end
subgraph sg_SDK["JL OTA SDK (jl_ota_2.1.1)"]
OTAImpl["OTAImpl"]
CbHelper["UpgradeCallbackHelper"]
Timers["回连定时器组<br/>_ReconnectTimer / _WaitDeviceOffLineTimer<br/>_TaskTimer"]
end
subgraph sg_Device["设备端"]
Dev["BLE 设备<br/>(单备份升级模式)"]
end
BLE -->|"onConnectStateSuccess / onConnectStateDisconnect<br/>onScanFound / onReceiveData"| OTAWrapper
OTAWrapper -->|"startOTA(config, callback)"| OTAImpl
OTAImpl -->|"onNeedReconnect(ReConnectMsg)"| CbHelper
CbHelper -->|"回调"| OTAWrapper
OTAWrapper -->|"触发上层重连<br/>(仅连接通讯通道)"| BLE
OTAImpl -->|"RECONNECT_DEVICE_DELAY=1000ms<br/>RECONNECT_DEVICE_TIMEOUT"| Timers
BLE -->|"BLE 连接/数据传输"| Dev
OTAImpl -->|"setDeviceBLEMac / _setReConnectMsg"| Dev
组件说明
| 组件 | 角色 | 与回连的关系 |
|---|---|---|
OTAWrapper | SDK 面向业务层的外观类(门面) | 接收上层蓝牙状态同步(onConnectStateSuccess 等),转发给 OTAImpl;也负责把 onNeedReconnect 等回调透传给上层 |
OTAImpl | OTA 流程核心引擎 | 持有 _ReConnectMsg、_ReconnectTimer、_WaitDeviceOffLineTimer;负责 _readyToReconnectDevice、_startReConnectDeviceTimeout 等内部回连逻辑 |
UpgradeCallbackHelper | 回调分发辅助类 | 把 onNeedReconnect、onProgress、onError 等事件安全地分发给上层注册的 OnUpgradeCallback |
| 回连定时器组 | 回连超时/延迟控制 | RECONNECT_DEVICE_DELAY = 1000(回连前延迟 1 秒)、RECONNECT_DEVICE_TIMEOUT(回连总超时,超时触发 ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112) |
| 上层蓝牙管理 | 小程序的 wx BLE API 封装 | 执行实际的"仅连接通讯通道"动作;若 isInnerReconnect() 返回 false,则由上层完全接管回连 |
设计意图:SDK 将蓝牙连接与数据收发抽离到上层(V2.0.0 起),因此回连动作本身由上层执行,SDK 只负责"何时需要回连"的决策与超时守护。这种分工让 SDK 不依赖具体的小程序蓝牙实现,同时通过回调与定时器保证回连动作必须在规定时间内完成。
触发时机与关键接口
触发时机:OnUpgradeCallback.onNeedReconnect
回连的触发入口是升级回调中的 onNeedReconnect。SDK 在设备完成 BootLoader 传输、即将重启进入升级模式时调用它。类型定义中特别注明了两条约束:
- 仅连接通讯通道(BLE 或 SPP)——上层在收到该回调时不要执行完整的"认证 + RCSP 初始化"流程,只需建立物理通讯链路;
- 用于单备份 OTA——双备份方案不依赖该机制。
/** 升级流程的回调 */
interface OnUpgradeCallback {
/** OTA开始*/
onStartOTA(): void;
/**需要回连的回调
* <p>
* 注意: 1.仅连接通讯通道(BLE or SPP)
* 2.用于单备份OTA</p>
*
* @param reConnectMsg 回连设备信息
*/
onNeedReconnect(reConnectMsg: ReConnectMsg): void;
/** 进度回调
*
* @param type 类型
* @param progress 进度
*/
onProgress(type: UpgradeType, progress: number): void;
/** OTA结束*/
onStopOTA(): void;
/** OTA取消*/
onCancelOTA(): void;
/** OTA失败
* @param error 错误码
* @param message 错误信息
*/
onError(error: number, message: string): void;
}
Source: libs/jl_ota_2.1.1.d.ts
回连信息:ReConnectMsg
onNeedReconnect 携带的 ReConnectMsg 封装了回连所需的设备信息:
/** 回连信息*/
declare class ReConnectMsg {
isSupportNewReconnectADV?: boolean;
/** rcsp协议中的BLE_Mac地址 */
deviceBleMac?: string;
copy(): ReConnectMsg;
toString(): string;
}
Source: libs/jl_ota_2.1.1.d.ts
字段含义:
| 字段 | 类型 | 说明 |
|---|---|---|
isSupportNewReconnectADV | boolean? | 设备是否支持"新回连广播"。支持时设备重启后会以特定广播方式快速被发现 |
deviceBleMac | string? | RCSP 协议中上报的 BLE MAC 地址,用于新回连方式的定向重连(不必全量扫描) |
这两个字段正是"新回连方式"的数据基础:只要拿到 deviceBleMac,上层即可直接按 MAC 过滤/定向连接;isSupportNewReconnectADV 则告诉上层设备是否具备快速回连广播能力。
开关一:OTAConfig.isSupportNewRebootWay
是否启用新回连方式,由 OTA 配置在开始升级前决定:
/** OTA 配置 */
declare class OTAConfig {
static readonly COMMUNICATION_WAY_BLE = 0;
static readonly COMMUNICATION_WAY_SPP = 1;
static readonly COMMUNICATION_WAY_USB = 2;
/** 通讯方式*/
communicationWay: number;
/** 是否支持新的回连方式*/
isSupportNewRebootWay: boolean;
/** 固件升级文件数据*/
updateFileData?: Uint8Array;
toString(): string;
}
Source: libs/jl_ota_2.1.1.d.ts
开关二:OTAWrapperOption.isInnerReconnect
是否由 SDK 内部执行回连,由 OTAWrapper 初始化选项决定。若上层自行处理回连,应返回 false,SDK 只负责回调通知:
const otaWrapperOption: OTAWrapperOption = {
/**是否需要认证。 在上层已经认证过,就不需要认证。**/
isUseAuth: () => {
return this._BluetoothConfigure.isUseAuth
},
/**是否需要回连。 在上层进行回连,就不需要内部回连。**/
isInnerReconnect: () => {
return true
},
// ... sanDevice / connectDevice / disconnectDevice / sendData ...
}
this._OTAWrapper = new OTAWrapper(otaWrapperOption)
Source: README.md
设计意图:
isInnerReconnect与onNeedReconnect是一对互补开关。isInnerReconnect = true表示 SDK 内部会利用OTAWrapperOption提供的connectDevice等能力自动完成回连;false则表示上层收到回调后自行执行回连(例如上层有更复杂的设备过滤逻辑时)。无论哪种方式,onNeedReconnect都会被回调,保证上层始终感知"设备即将重启回连"这一状态。
内部实现机制(OTAImpl)
SDK 内部由 OTAImpl 承载回连状态机,其私有成员与定时器直接对应回连机制的每个环节:
declare class OTAImpl {
static readonly WAITING_CMD_TIMEOUT: number;
static readonly WAITING_DEVICE_OFFLINE_TIMEOUT: number;
static readonly RECONNECT_DEVICE_DELAY = 1000;
static readonly RECONNECT_DEVICE_TIMEOUT: number;
private _ReConnectMsg;
private _OTADeviceBleMac;
private _ReconnectTimer;
private _WaitDeviceOffLineTimer;
// ...
/** 准备回连设备 */
private _readyToReconnectDevice;
private _setReConnectMsg;
/** 读取设备升级状态 */
private _queryUpgradeResult;
/** 进入升级状态 */
private _enterUpdateMode;
private _startWaitDeviceOffLineTimeOut;
private _stopWaitDeviceOffLineTimeOut;
private _startReConnectDeviceTimeout;
private _stopReConnectDeviceTimeout;
private _callbackReConnectDevice;
// ...
}
Source: libs/jl_ota_2.1.1.d.ts
回连机制内部的几个关键设计点:
RECONNECT_DEVICE_DELAY = 1000:设备断开后并非立即回连,而是等待 1 秒。这是为了给设备留出重启、拉起升级模式广播的时间窗口,避免"设备还没准备好就连接"导致连接失败。_WaitDeviceOffLineTimer/WAITING_DEVICE_OFFLINE_TIMEOUT:SDK 先等待设备真正离线(断开连接),确认设备进入了重启流程,再进入回连准备阶段。设备离线状态通过上层onConnectStateDisconnect同步。_startReConnectDeviceTimeout/RECONNECT_DEVICE_TIMEOUT:从开始回连到回连成功有一个总超时。超时后 SDK 会回调onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT, ...)终止升级流程,避免上层无限等待。_setReConnectMsg与setDeviceBLEMac:回连信息(ReConnectMsg)与设备 BLE MAC 在升级过程中被记录,_readyToReconnectDevice阶段将其组装并通过_callbackReConnectDevice触发onNeedReconnect。_queryUpgradeResult/_enterUpdateMode:回连成功后,SDK 会继续查询设备升级状态并再次进入升级模式,从断点继续传输固件,而不是从头开始。
整个流程中 SDK 通过 _removeAllTimer 统一清理定时器,保证在 release()、OTA 结束或失败时不会残留定时器导致内存泄漏或重复回调。
核心回连流程
下图描述单备份 OTA 中设备重启回连的完整时序:
sequenceDiagram
participant App as 上层业务 (OTAWrapper)
participant SDK as OTAImpl (SDK)
participant Dev as BLE 设备
App->>SDK: startOTA(config, callback)
SDK->>Dev: 传输 BootLoader (UPGRADE_TYPE_CHECK_FILE)
Dev-->>SDK: 需要重启进入升级模式
SDK->>SDK: 记录 ReConnectMsg (deviceBleMac / isSupportNewReconnectADV)
SDK->>App: onNeedReconnect(reConnectMsg)
App->>App: 仅连接通讯通道 (BLE/SPP) 回连设备
App->>Dev: 重新建立 BLE 连接
App->>SDK: onConnectStateSuccess(dev) 同步连接状态
SDK->>Dev: 查询升级状态 / 再次进入升级模式
Dev-->>SDK: 从断点继续传输固件
SDK->>App: onProgress(UPGRADE_TYPE_FIRMWARE, progress)
SDK->>App: onStopOTA() / onError(...)
flowchart TD
Start(["设备重启,连接断开"]) --> Offline{"等待设备离线<br/>(WAITING_DEVICE_OFFLINE_TIMEOUT)"}
Offline -->|"超时未离线"| Err1["onError(OTA失败)"]
Offline -->|"已离线"| Delay["延迟 1s<br/>(RECONNECT_DEVICE_DELAY=1000)"]
Delay --> Notify["回调 onNeedReconnect(ReConnectMsg)"]
Notify --> Choose{"isInnerReconnect?"}
Choose -->|"true (内部回连)"| Inner["SDK 调用 connectDevice 定向回连"]
Choose -->|"false (上层回连)"| Outer["上层执行回连<br/>(仅连接通讯通道)"]
Inner --> Connected{"回连成功?"}
Outer --> Connected
Connected -->|"否,且超时"| Err2["onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112)"]
Connected -->|"是"| Resume["查询升级状态,继续传输固件"]
Resume --> Done["onProgress / onStopOTA"]
Err1 --> End([结束])
Err2 --> End
Done --> End
关键点:回连阶段不重新认证、不重新初始化 RCSP(
onNeedReconnect注释明确"仅连接通讯通道")。连接成功后通过onConnectStateSuccess通知OTAWrapper,SDK 据此恢复升级上下文。
使用示例
示例一:初始化 OTAWrapper 并启用内部回连
在业务层初始化 OTAWrapper 时,通过 isInnerReconnect 决定回连的执行方。true 表示 SDK 内部回连,上层仍需提供 connectDevice 等蓝牙能力:
//OTAWrapper 初始化
const otaWrapperOption: OTAWrapperOption = {
/**是否需要认证。 在上层已经认证过,就不需要认证。**/
isUseAuth: () => {
return this._BluetoothConfigure.isUseAuth
},
/**是否需要回连。 在上层进行回连,就不需要内部回连。**/
isInnerReconnect: () => {
return true
},
/**扫描设备**/
sanDevice: () => {
//todo 实现蓝牙扫描操作
},
/**连接设备**/
connectDevice: (device: BluetoothDevice) => {
//todo 实现蓝牙连接操作
},
/**断开设备**/
disconnectDevice: (device: BluetoothDevice) => {
//todo 实现蓝牙断开操作
},
/**发送数据(非必须实现),
* 必须实现的情况:
* - 1.内部创建并管理RCSPImpl, 即OTAWrapperOption.getRCSPImpl未实现
* - 2.需要进行认证, 即OTAWrapperOption.isUseAuth返回false
* **/
sendData: (device: BluetoothDevice, data: Uint8Array) => {
//todo 实现蓝牙发数操作
}
}
this._OTAWrapper = new OTAWrapper(otaWrapperOption)
Source: README.md
示例二:同步蓝牙连接状态(回连成功的通知通道)
上层蓝牙连接成功/断开/失败时,必须同步给 OTAWrapper。回连成功后正是通过 onConnectStateSuccess 让 SDK 感知"设备已重新连接",从而继续升级:
this._bluetoothInstance.addConnectCallback({
onMTUChange: (dev: any, mtu) => {
BleSendDataHandler.setMtu(dev.deviceId, mtu)
this._onConnectStateMTUChange(dev, mtu)
}, onConnectSuccess: (dev: any) => {
// 通知 OTAWrapper 蓝牙连接成功
this._OTAWrapper.onConnectStateSuccess(dev)
this._onConnectStateSuccess(dev)
}, onConnectFailed: (dev: any, _err) => {
// 通知 OTAWrapper 蓝牙连接失败
this._OTAWrapper.onConnectStateFailed(dev)
this._onConnectStateFailed(dev)
}, onConnectDisconnect: (dev: any) => {
// 通知 OTAWrapper 蓝牙连接断开
this._OTAWrapper.onConnectStateDisconnect(dev)
this._onConnectStateDisconnect(dev)
}
})
Source: README.md
同样地,扫描结果(onScanFound)与数据推送(onReceiveData)也必须转发给 OTAWrapper,分别用于传统回连方式下的设备发现,以及回连后恢复数据收发(见 README 第三步、第四步的 addScanCallback 与 BleDataHandler.addCallbacks)。
示例三:开始 OTA 并处理回连回调
创建 OTAConfig 时开启新回连方式,并在 OnUpgradeCallback 中实现 onNeedReconnect:
/*--- 开始执行OTA升级 ---*/
//创建OTA配置项
const otaConfig: OTAConfig = new OTAConfig()
//是否支持新的回连方式
otaConfig.isSupportNewRebootWay = true
//固件升级文件数据
otaConfig.updateFileData = this.upgradeData
//升级目标设备
const device = connectedDevices[0]
const onUgradeCallback: OnUpgradeCallback = {
onStartOTA: () => {
// 开始升级
},
onNeedReconnect: (reConnectMsg: ReConnectMsg) => {
// 正在回连
},
onProgress: (type: UpgradeType, progress: number) => {
// 升级进度回调
if (type == UpgradeType.UPGRADE_TYPE_CHECK_FILE) {
// 校验文件(传输BootLoader)
} else if (type == UpgradeType.UPGRADE_TYPE_FIRMWARE) {
// 传输升级内容
}
},
onStopOTA: () => {
// 升级结束
},
onCancelOTA: () => {
// 升级取消
},
onError: (error: number, message: string) => {
// 升级失败
},
}
this._OTAWrapper.startOTA(device, otaConfig, onUgradeCallback)
Source: README.md
注意:
onNeedReconnect回调内通常只做一件事——依据reConnectMsg(尤其是deviceBleMac)重新连接设备;若isInnerReconnect()已返回true,上层甚至可以只更新 UI 提示"正在回连",实际的连接动作由 SDK 内部完成。
配置选项
| 配置项 | 位置 | 类型 | 默认/示例 | 说明 |
|---|---|---|---|---|
isInnerReconnect | OTAWrapperOption | () => boolean | () => true | 是否由 SDK 内部执行回连;上层自行回连时返回 false |
isSupportNewRebootWay | OTAConfig | boolean | true | 是否支持新回连方式(基于 BLE MAC 定向回连) |
communicationWay | OTAConfig | number | OTAConfig.COMMUNICATION_WAY_BLE = 0 | 通讯方式:BLE / SPP / USB;回连需与该通道一致 |
updateFileData | OTAConfig | Uint8Array? | — | 固件升级文件数据 |
RECONNECT_DEVICE_DELAY | OTAImpl 常量 | number | 1000 | 设备离线后延迟 1 秒再回连,等待设备进入升级模式广播 |
RECONNECT_DEVICE_TIMEOUT | OTAImpl 常量 | number | SDK 内置 | 回连总超时;超时回调 ERROR_OTA_RECONNECT_DEVICE_TIMEOUT |
WAITING_DEVICE_OFFLINE_TIMEOUT | OTAImpl 常量 | number | SDK 内置 | 等待设备真正离线的超时上限 |
isSupportNewReconnectADV | ReConnectMsg | boolean? | — | 设备是否支持新回连广播(由 SDK 从设备读取,只读) |
deviceBleMac | ReConnectMsg | string? | — | RCSP 协议上报的 BLE MAC,用于定向回连(只读) |
API 参考
onNeedReconnect(reConnectMsg: ReConnectMsg): void
OnUpgradeCallback 中的回连回调。设备完成 BootLoader 传输、即将重启进入升级模式时被调用。
参数:
reConnectMsg(ReConnectMsg):回连设备信息,包含deviceBleMac(RCSP 上报的 BLE MAC)与isSupportNewReconnectADV(是否支持新回连广播)。
返回值: 无。
注意事项:
- 回调内仅连接通讯通道(BLE 或 SPP),不要重复执行认证与 RCSP 初始化。
- 仅用于单备份 OTA。
- 回连完成后必须通过
OTAWrapper.onConnectStateSuccess(dev)同步连接状态,SDK 才能继续升级。
Source: libs/jl_ota_2.1.1.d.ts
OTAConfig.isSupportNewRebootWay: boolean
OTAConfig 配置项。置为 true 表示采用新回连方式:SDK 会记录 RCSP 上报的 deviceBleMac 并组装 ReConnectMsg,回连时按 MAC 定向连接,且支持设备的新回连广播。
ReConnectMsg.copy(): ReConnectMsg / ReConnectMsg.toString(): string
copy():深拷贝回连信息,供 SDK 内部保存快照使用。toString():调试日志输出回连信息的字符串表示。
OTAImpl 内部方法(SDK 内部使用,供理解机制)
| 方法 | 作用 |
|---|---|
_readyToReconnectDevice() | 准备回连设备:组装 ReConnectMsg、启动回连延迟/超时定时器 |
_setReConnectMsg(msg) | 保存回连信息快照(升级过程中由设备信息填充) |
setDeviceBLEMac(mac) | 设置 RCSP 协议上报的设备 BLE MAC,供定向回连使用 |
_startReConnectDeviceTimeout() / _stopReConnectDeviceTimeout() | 启动/停止回连总超时守护 |
_startWaitDeviceOffLineTimeOut() / _stopWaitDeviceOffLineTimeOut() | 启动/停止"等待设备离线"超时守护 |
_callbackReConnectDevice(msg) | 触发 onNeedReconnect 回调分发 |
_removeAllTimer() | 清理全部定时器(回连、离线等待、任务超时),防止泄漏 |
相关错误码(OTAError)
| 常量 | 值 | 说明 |
|---|---|---|
ERROR_OTA_RECONNECT_DEVICE_TIMEOUT | -112 | 回连设备超时(RECONNECT_DEVICE_TIMEOUT 到期仍未连上) |
ERROR_OTA_USE_CANCEL | -113 | 用户取消升级(单备份方案下 cancelOTA() 无效,因此不会出现此码) |
ERROR_DEVICE_OFFLINE | -33 | 设备离线(回连前若设备长期离线可能触发) |
ERROR_OTA_IN_PROGRESS | -110 | OTA 进行中(重复触发回连/重复 startOTA 时可能遇到) |
Source: libs/jl_ota_2.1.1.d.ts
失败模式、边界情况与并发
回连超时
RECONNECT_DEVICE_TIMEOUT 到期仍未能建立连接时,SDK 回调 onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112)。典型诱因:
- 设备重启后长时间未进入可发现/可连接状态(固件异常、电量不足);
- 用户走远导致信号丢失;
- iOS 系统蓝牙缓存导致定向连接失败(V2.1.1 已针对性修复,见下文版本历史)。
上层应在此错误回调中提示用户"回连失败,请手动重新连接后重试升级"。
等待设备离线超时
设备在预期时间内未断开(WAITING_DEVICE_OFFLINE_TIMEOUT 到期),说明设备未按预期重启,SDK 走失败分支。这是对"假死"状态的保护:避免设备既没断开又没回连时流程卡死。
单备份方案下取消无效
cancelOTA() 在单备份方案下无效(类型注释明确说明),因此单备份升级一旦进入回连阶段,用户无法中途取消,只能等待成功或失败。业务层 UI 上应避免在回连阶段展示"取消升级"操作。
并发与状态一致性
- 回连期间
OTAImpl持有_ReConnectMsg与_OTADeviceBleMac,升级流程串行执行;重复调用startOTA()会因_checkIsNotOTA校验(ERROR_OTA_IN_PROGRESS)被拒绝。 - 所有定时器统一由
_removeAllTimer清理:release()、onDeviceDisconnect()失败路径、OTA 结束时都会调用,防止回连定时器在 OTA 结束后仍触发回调造成竞态。 - 上层回连成功后必须尽快调用
onConnectStateSuccess,SDK 的回连超时倒计时不因上层动作而暂停,若上层回连耗时超过RECONNECT_DEVICE_TIMEOUT,即使连接已建立也可能收到超时错误——因此"仅连接通讯通道"的要求是为了让回连动作尽量快。
性能与运维注意事项
- 回连延迟是有意的:
RECONNECT_DEVICE_DELAY = 1000(1 秒)用于等待设备重启并进入升级模式广播。不要在上层自行缩短该等待,否则设备未就绪时连接会立即失败,反而触发超时错误。 - 定向回连优于全量扫描:启用
isSupportNewRebootWay后,回连利用ReConnectMsg.deviceBleMac定向连接,避免重新发起全量 BLE 扫描,既快又省电,对 iOS 系统蓝牙队列也更友好。 - iOS 16 兼容性:V2.1.1 版本历史明确记录"修复 iOS16 单备份升级回连搜不到设备问题"(见 README.md 版本历史)。使用自动回连时应确保小程序端使用 SDK 2.1.1 及以上版本。
- 日志排查:SDK 提供详细日志输出,可通过日志观察"回连开始 → 连接成功 → 恢复传输"的时序;小程序端可用
vConsole查看实时日志。回连异常时重点核对:是否收到onNeedReconnect、onConnectStateSuccess是否在超时前同步、ReConnectMsg.deviceBleMac是否有值。 - 超时参数不可运行时调整:
RECONNECT_DEVICE_TIMEOUT、WAITING_DEVICE_OFFLINE_TIMEOUT是OTAImpl的静态常量,由 SDK 内置,上层无法修改;若业务需要更长回连窗口,应通过isInnerReconnect: () => false接管回连并自行控制超时。
扩展点
- 上层接管回连(
isInnerReconnect = false):当业务层有特殊的设备过滤、多设备选择或需要向用户展示回连进度 UI 时,可关闭内部回连,在onNeedReconnect回调中自行完成"仅连接通讯通道"的动作,再通过onConnectStateSuccess交还控制权。 - 新回连方式(
isSupportNewRebootWay = true):设备侧若支持新回连广播(isSupportNewReconnectADV),回连更快更稳;该能力由固件与 SDK 共同决定,上层只需在创建OTAConfig时开启。 - 回调扩展(
OnUpgradeCallback):onNeedReconnect与onProgress/onError等回调配合,可实现完整的升级状态机展示(校验文件 → 回连 → 传输固件 → 结束),业务层可在这些回调之间自由插入 UI 与埋点逻辑。
测试覆盖观察
仓库为 SDK 集成示例项目,未发现针对回连机制的独立单元测试文件。可验证的保障来自:
- 类型定义(
libs/jl_ota_2.1.1.d.ts)对回连接口的契约约束(回调时机、仅连接通讯通道、单备份限定); - README 集成示例(初始化、状态同步、回调实现)构成的上层集成路径;
- 版本历史中的回归记录(V2.1.1 修复 iOS16 回连搜不到设备)。
实际回归测试建议:在真机上模拟"传输 BootLoader 后断电重启"场景,验证 onNeedReconnect 触发、onConnectStateSuccess 同步与续传进度,并覆盖"回连超时 → onError(-112)"的失败路径。
Related Links
- README.md — OTAWrapper 初始化与回调实现(本页示例的完整上下文)
- libs/jl_ota_2.1.1.d.ts — 回连相关类型定义
- libs/jl_ota_2.1.1.js — SDK 运行时实现
- libs/jl_rcsp_ota_2.1.1.js — RCSP OTA 协议(BLE MAC 上报来源)
- README_en.md — Auto Reconnect 特性说明(英文)
- 相关目录页:OTA 升级主流程(单备份/双备份)、OTAWrapper 初始化、认证机制