feat(lefu): 切后台挂起连接、回前台自动重连

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-08-25 20:57:00 +08:00
co-authored by Claude Opus 4.7
parent 3dea0382f7
commit e95d28a87b
2 changed files with 73 additions and 7 deletions
+22 -2
View File
@@ -1,6 +1,9 @@
App<IAppOption>({ import { leFuService } from './lefu/index'
App<IAppOption>({
globalData: { globalData: {
operationsEngineer: false operationsEngineer: false,
wasConnected: false
}, },
onLaunch() { onLaunch() {
@@ -15,6 +18,23 @@
} }
}, },
onHide() {
// 切后台:记录连接状态,挂起(断开但保留缓存设备,回前台可重连)
const wasConnected = leFuService.isConnected
this.globalData.wasConnected = wasConnected
if (wasConnected) {
leFuService.suspend()
}
},
onShow() {
// 回前台:如果之前连接过,自动重连
if (this.globalData.wasConnected) {
this.globalData.wasConnected = false
leFuService.autoConnect()
}
},
getWxLoginCode(): Promise<string> { getWxLoginCode(): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wx.login({ wx.login({
+49 -3
View File
@@ -45,7 +45,18 @@ class LeFuService {
private _reconnectTimer: number | null = null private _reconnectTimer: number | null = null
/** 保活心跳定时器 */ /** 保活心跳定时器 */
private _keepAliveTimer: number | null = null private _keepAliveTimer: number | null = null
/** 最近一次连接/扫描到的原始设备(用于断线重连) */ /**
* 最近一次连接/扫描到的原始设备(内存缓存)
* 用途:
* 1. 意外断线时自动重连(_doReconnect / connectState READY 分支)
* 2. 切后台回前台后自动重连(autoConnect
* 3. 业务层通过 lastRawDevice 判断「当前连接的是哪台设备」
* 生命周期:
* - connect() 时写入
* - disconnect() 主动断开时清空(用户主动断开,不再需要重连)
* - suspend() 切后台时保留(回前台 autoConnect 靠它重连)
* - 意外断开时保留(自动重连靠它)
*/
private _lastRawDevice: RawDevice | null = null private _lastRawDevice: RawDevice | null = null
// ─── 事件回调(每个事件支持多个监听者,用 Set 存储) ─── // ─── 事件回调(每个事件支持多个监听者,用 Set 存储) ───
@@ -211,8 +222,10 @@ class LeFuService {
plugin.bus.subscribe('deviceWillDisconnect', () => { plugin.bus.subscribe('deviceWillDisconnect', () => {
console.warn(TAG, 'bus[deviceWillDisconnect]intentionalConnect:', this._intentionalConnect) console.warn(TAG, 'bus[deviceWillDisconnect]intentionalConnect:', this._intentionalConnect)
this._stopKeepAlive() this._stopKeepAlive()
if (this._activeProtocol) {
this._activeProtocol = null this._activeProtocol = null
this._onDisconnectedCbs.forEach(cb => cb()) this._onDisconnectedCbs.forEach(cb => cb())
}
if (!this._intentionalConnect) { if (!this._intentionalConnect) {
this._doReconnect() this._doReconnect()
} }
@@ -245,14 +258,47 @@ class LeFuService {
} }
/** /**
* 主动断开连接 * 主动断开连接(用户主动操作:断开、退出登录、取消配对)
* 标记主动断开以阻止自动重连,并停止保活 * - 断开蓝牙连接、停止保活
* - 清理 _activeProtocol(主动断开立即清,不依赖后台事件,避免残留)
* - 清空 _lastRawDevice(主动断开后不再需要自动重连,避免残留)
*/ */
disconnect(): void { disconnect(): void {
console.log(TAG, 'disconnect()') console.log(TAG, 'disconnect()')
this._intentionalConnect = true this._intentionalConnect = true
this._stopKeepAlive() this._stopKeepAlive()
plugin.Blue.disconnect() plugin.Blue.disconnect()
if (this._activeProtocol) {
this._activeProtocol = null
this._onDisconnectedCbs.forEach(cb => cb())
}
this._lastRawDevice = null
}
/**
* 切后台挂起(小程序 onHide 时调用)
* 和 disconnect 的唯一区别:断开连接、清理 _activeProtocol,但【保留 _lastRawDevice】,
* 这样回前台时 autoConnect 才能用缓存的设备重连。
*/
suspend(): void {
console.log(TAG, 'suspend()')
this._intentionalConnect = true
this._stopKeepAlive()
plugin.Blue.disconnect()
if (this._activeProtocol) {
this._activeProtocol = null
this._onDisconnectedCbs.forEach(cb => cb())
}
}
/**
* 回前台自动重连(小程序 onShow 时调用)
* 用 suspend 保留的 _lastRawDevice 重连;已连接或无缓存设备则跳过。
*/
autoConnect(): void {
if (this.isConnected) return
if (!this._lastRawDevice) return
this.connect(this._lastRawDevice)
} }
/** /**