feat(lefu): 切后台挂起连接、回前台自动重连
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
3dea0382f7
commit
e95d28a87b
+22
-2
@@ -1,6 +1,9 @@
|
||||
App<IAppOption>({
|
||||
import { leFuService } from './lefu/index'
|
||||
|
||||
App<IAppOption>({
|
||||
globalData: {
|
||||
operationsEngineer: false
|
||||
operationsEngineer: false,
|
||||
wasConnected: false
|
||||
},
|
||||
|
||||
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> {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.login({
|
||||
|
||||
@@ -45,7 +45,18 @@ class LeFuService {
|
||||
private _reconnectTimer: 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
|
||||
|
||||
// ─── 事件回调(每个事件支持多个监听者,用 Set 存储) ───
|
||||
@@ -211,8 +222,10 @@ class LeFuService {
|
||||
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
||||
console.warn(TAG, 'bus[deviceWillDisconnect],intentionalConnect:', this._intentionalConnect)
|
||||
this._stopKeepAlive()
|
||||
this._activeProtocol = null
|
||||
this._onDisconnectedCbs.forEach(cb => cb())
|
||||
if (this._activeProtocol) {
|
||||
this._activeProtocol = null
|
||||
this._onDisconnectedCbs.forEach(cb => cb())
|
||||
}
|
||||
if (!this._intentionalConnect) {
|
||||
this._doReconnect()
|
||||
}
|
||||
@@ -245,14 +258,47 @@ class LeFuService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动断开连接
|
||||
* 标记主动断开以阻止自动重连,并停止保活。
|
||||
* 主动断开连接(用户主动操作:断开、退出登录、取消配对)
|
||||
* - 断开蓝牙连接、停止保活
|
||||
* - 清理 _activeProtocol(主动断开立即清,不依赖后台事件,避免残留)
|
||||
* - 清空 _lastRawDevice(主动断开后不再需要自动重连,避免残留)
|
||||
*/
|
||||
disconnect(): void {
|
||||
console.log(TAG, 'disconnect()')
|
||||
this._intentionalConnect = true
|
||||
this._stopKeepAlive()
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user