fix(scale): 修复子设备断线后重连慢及连接状态竞态问题

- onDeviceDisconnected 时同步清除 UDP 缓存,使子设备 5s 内即可重连,不再等待指数退避
- ScaleWebSocketServer 用 connectionCount 计数器替代 connections.isNullOrEmpty(),消除 onClose 竞态导致子设备 UI 状态不更新的问题
This commit is contained in:
2026-05-06 09:03:40 +08:00
parent 9cfc481cf3
commit e990652981
2 changed files with 12 additions and 3 deletions
@@ -156,7 +156,11 @@ object ScaleServiceManager {
val client = ScaleWebSocketClient().also { val client = ScaleWebSocketClient().also {
it.onScaleData = { data -> aggregator?.onRemoteScaleData(data) } it.onScaleData = { data -> aggregator?.onRemoteScaleData(data) }
it.onScaleEvent = { event -> _onScaleEvent?.invoke(event) } it.onScaleEvent = { event -> _onScaleEvent?.invoke(event) }
it.onDeviceDisconnected = { remoteId -> aggregator?.removeDevice(remoteId) } it.onDeviceDisconnected = { remoteId ->
aggregator?.removeDevice(remoteId)
// 清除 UDP 缓存,确保子设备下次广播时能重新触发 onDeviceFound,立即重连而非等待指数退避
udpReceiver?.removeDevice(remoteId)
}
it.onDeviceConnected = { remoteId -> it.onDeviceConnected = { remoteId ->
// 子设备连接成功时,从 Room 读取全量配置并单独推送给该设备 // 子设备连接成功时,从 Room 读取全量配置并单独推送给该设备
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
@@ -117,7 +117,11 @@ class ScaleWebSocketServer(private val deviceId: String, private val context: Co
private inner class InternalServer(port: Int) : private inner class InternalServer(port: Int) :
WebSocketServer(InetSocketAddress(port)) { WebSocketServer(InetSocketAddress(port)) {
/** 当前活跃连接计数,用于替代 connections.isNullOrEmpty() 避免竞态 */
private var connectionCount = 0
override fun onOpen(conn: WebSocket, handshake: ClientHandshake) { override fun onOpen(conn: WebSocket, handshake: ClientHandshake) {
connectionCount++
Log.d(TAG, "主设备已连接: ${conn.remoteSocketAddress}") Log.d(TAG, "主设备已连接: ${conn.remoteSocketAddress}")
onConnectionChanged?.invoke(true) onConnectionChanged?.invoke(true)
// 新客户端连接后,立即推送所有秤的最新数据 // 新客户端连接后,立即推送所有秤的最新数据
@@ -132,8 +136,9 @@ class ScaleWebSocketServer(private val deviceId: String, private val context: Co
override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) { override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) {
Log.d(TAG, "主设备已断开: ${conn.remoteSocketAddress}, reason=$reason") Log.d(TAG, "主设备已断开: ${conn.remoteSocketAddress}, reason=$reason")
// 若已无任何连接,通知子设备 UI 更新为未连接状 // 用计数器判断是否还有活跃连接,避免依赖 connections 集合的移除时机导致竞
if (server?.connections.isNullOrEmpty()) { if (--connectionCount <= 0) {
connectionCount = 0
onConnectionChanged?.invoke(false) onConnectionChanged?.invoke(false)
} }
} }