From b83bf753302e0b75db6670c7d64bf04970151243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9C=E8=99=9E=E6=B8=A0=E6=88=90=E2=80=9D?= <“yuqucheng2006@qq.com”> Date: Tue, 14 Jul 2026 08:56:20 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E8=93=9D=E7=89=99&=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80):=20=E4=BC=98=E5=8C=96=E5=A4=9A=E9=A1=B9=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=B9=B6=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 更新多语言文件中星期的英文缩写为完整标准写法 2. 移除OTA传输中的额外延迟,优化传输速度 3. 蓝牙连接时请求高吞吐量MTU和连接优先级 4. 修复蚊虫数据请求前初始化容器的时序问题 5. 重构BLE帧解析逻辑,批量处理帧避免协程积压 --- Assets/Res/language/language.json | 8 +- .../Bluetooth/BLECommunicationManager.cs | 77 ++++++++++--------- Assets/Scripts/Bluetooth/BluetoothManager.cs | 9 +++ Assets/Scripts/Bluetooth/OTAManager.cs | 6 -- .../Scripts/UI/Pages/HomePage/HomePageCtrl.cs | 8 +- 5 files changed, 59 insertions(+), 49 deletions(-) diff --git a/Assets/Res/language/language.json b/Assets/Res/language/language.json index 5503c37..8359057 100644 --- a/Assets/Res/language/language.json +++ b/Assets/Res/language/language.json @@ -652,22 +652,22 @@ { "key": "100131", "zh": "一", - "en": "M" + "en": "Mon" }, { "key": "100132", "zh": "二", - "en": "T" + "en": "Tue" }, { "key": "100133", "zh": "三", - "en": "W" + "en": "Wed" }, { "key": "100134", "zh": "四", - "en": "Th" + "en": "Thu" }, { "key": "100135", diff --git a/Assets/Scripts/Bluetooth/BLECommunicationManager.cs b/Assets/Scripts/Bluetooth/BLECommunicationManager.cs index 2fd276e..3e0a774 100644 --- a/Assets/Scripts/Bluetooth/BLECommunicationManager.cs +++ b/Assets/Scripts/Bluetooth/BLECommunicationManager.cs @@ -2337,57 +2337,60 @@ namespace Kill.Bluetooth /// private void TryParseFrameInternal() { - byte[] buffer = _receiveBuffer.ToArray(); + // 收集所有完整帧,避免频繁 StartCoroutine 和 return 导致积压 + var frames = new List(); + int totalRemoved = 0; - // 查找帧头 - for (int i = 0; i < buffer.Length - 1; i++) + while (totalRemoved < _receiveBuffer.Count) { - if (buffer[i] == BLEConstants.FRAME_HEADER_1 && - buffer[i + 1] == BLEConstants.FRAME_HEADER_2) + int searchStart = totalRemoved; + byte[] buffer = _receiveBuffer.ToArray(); + bool found = false; + + for (int i = searchStart; i < buffer.Length - 1; i++) { - // 检查是否有足够的数据长度字段 - if (i + 4 >= buffer.Length) + if (buffer[i] == BLEConstants.FRAME_HEADER_1 && + buffer[i + 1] == BLEConstants.FRAME_HEADER_2) { - continue; - } + if (i + 4 >= buffer.Length) continue; - byte dataLength = buffer[i + 4]; - int totalFrameLength = 7 + dataLength; // 帧头(2) + 命令(1) + 读写(1) + 长度(1) + 数据(dataLength) + CRC(2) + byte dataLength = buffer[i + 4]; + int totalFrameLength = 7 + dataLength; - // 检查是否有完整的帧 - if (i + totalFrameLength > buffer.Length) - { - continue; - } + if (i + totalFrameLength > buffer.Length) continue; - // 提取帧数据 - byte[] frameBytes = new byte[totalFrameLength]; - Buffer.BlockCopy(buffer, i, frameBytes, 0, totalFrameLength); + byte[] frameBytes = new byte[totalFrameLength]; + Buffer.BlockCopy(buffer, i, frameBytes, 0, totalFrameLength); - // 解析帧 - if (BLEFrame.TryParse(frameBytes, out BLEFrame frame)) - { - // 从缓冲区移除已解析的数据 - int removeLength = i + totalFrameLength; - _receiveBuffer.RemoveRange(0, removeLength); - - // 在锁外处理帧,避免死锁和重入问题 - // 使用异步方式在下一帧处理 - StartCoroutine(HandleFrameAsync(frame)); - return; - } - else - { - LogWarning("帧解析失败 (CRC校验可能失败)"); + if (BLEFrame.TryParse(frameBytes, out BLEFrame frame)) + { + frames.Add(frame); + totalRemoved += (i - searchStart) + totalFrameLength; + searchStart = totalRemoved; + found = true; + break; + } + else + { + LogWarning("帧解析失败 (CRC校验可能失败)"); + } } } + + if (!found) break; } - // 清理过期的缓冲区数据 (保留最后100字节) + // 移除已解析的数据 + if (totalRemoved > 0) + _receiveBuffer.RemoveRange(0, totalRemoved); + + // 清理过期缓冲区 if (_receiveBuffer.Count > 200) - { _receiveBuffer.RemoveRange(0, _receiveBuffer.Count - 100); - } + + // 在锁外批量处理帧 + foreach (var frame in frames) + StartCoroutine(HandleFrameAsync(frame)); } /// diff --git a/Assets/Scripts/Bluetooth/BluetoothManager.cs b/Assets/Scripts/Bluetooth/BluetoothManager.cs index 5c299c2..ee4d0d5 100644 --- a/Assets/Scripts/Bluetooth/BluetoothManager.cs +++ b/Assets/Scripts/Bluetooth/BluetoothManager.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Kill.Core; using Kill.UI; using Kill.UI.Components; +using static BluetoothLEHardwareInterface; namespace Kill.Bluetooth { @@ -828,6 +829,14 @@ namespace Kill.Bluetooth OnConnected?.Invoke(address); + // 请求高吞吐量:MTU 512 + 高优先级连接间隔 + BluetoothLEHardwareInterface.RequestMtu(address, 512, (addr, mtu) => + { + Log($"MTU 协商完成: {mtu} 字节"); + }); + BluetoothLEHardwareInterface.BluetoothConnectionPriority(ConnectionPriority.High); + Log("已请求高优先级 BLE 连接"); + // 延迟通知连接成功并可通信 Invoke(nameof(NotifyConnectedSuccess), 0.5f); } diff --git a/Assets/Scripts/Bluetooth/OTAManager.cs b/Assets/Scripts/Bluetooth/OTAManager.cs index 4507384..6b7f815 100644 --- a/Assets/Scripts/Bluetooth/OTAManager.cs +++ b/Assets/Scripts/Bluetooth/OTAManager.cs @@ -284,12 +284,6 @@ namespace Kill.Bluetooth // 报告进度(无重试) OnTransferProgress?.Invoke(i + 1, _totalPackets, 0, 0); - - // 每包之间添加小延迟,避免设备处理不过来 - if (i < _totalPackets - 1) - { - yield return new WaitForSeconds(0.01f); - } } SetState(OTAState.Ending); diff --git a/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs b/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs index 29a7c5d..d37cba5 100644 --- a/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs +++ b/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs @@ -1498,6 +1498,10 @@ namespace Kill.UI.Pages Debug.Log($"检测到 {count.Count} 条蚊虫数据,正在请求..."); + // 在请求前先初始化接收容器,避免通知先于主线程回调到达导致数据丢失 + mosquitoDatas = new List(); + aimMosquitoDataCount = (int)count.Count; + // 步骤2: 请求所有蚊虫数据 BLECommunicationManager.Instance.RequestMosquitoData(count.Count, (success) => { @@ -1509,12 +1513,12 @@ namespace Kill.UI.Pages tip=tip.Replace("{0}",count.ToString()); ToastUI.ShowText(tip); Debug.Log($"已请求 {count.Count} 条蚊虫数据,等待接收..."); - mosquitoDatas=new List(); - aimMosquitoDataCount=(int)count.Count; } else { Debug.Log("蚊虫数据请求失败"); + mosquitoDatas = null; + aimMosquitoDataCount = 0; LoadingUI.Hide(); } });