You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac端Web Bluetooth指令重复发送问题排查求助

排查与解决Mac端Chrome下Web Bluetooth指令重复发送问题

核心问题定位

你的代码存在无终止条件的递归重试逻辑,当Mac端Chrome的蓝牙连接状态判断出现偏差时,会触发无限递归调用writeValue,导致指令重复发送。同时Mac Chrome的Web Bluetooth实现与Windows端存在细节差异,需要针对性调整。

排查思路与修复技巧

1. 修复递归重试的无限循环问题

当前代码在设备未连接时递归调用自身,但没有终止限制,一旦Mac端device.gatt.connected判断延迟或误判,就会无限重复执行。给重试添加最大次数限制:

export async function writeValue(deviceId, serviceId, characteristicId, value, retryCount = 0) {
    const maxRetries = 3; // 设置最大重试次数
    var device = getDevice(deviceId);

    console.log("START WRITE VALUE.JS", value);

    if (device.gatt.connected) {
        try {
            const service = await device.gatt.getPrimaryService("e2088282-4fde-42f9-bb22-6ec3c7ed8f91");
            const characteristic = "6d92661d-f429-4d67-929b-28e7a9780912";
            const ch = await service.getCharacteristic(characteristic);
            
            await ch.writeValue(new Uint8Array(value));
            console.log("Write operation successful");
        } catch (error) { 
            console.error("Error during write operation:", error); 
        }
    } else {
        if (retryCount >= maxRetries) {
            console.error("Max retries reached, device not connected");
            return;
        }
        await sleep(1000);
        await writeValue(deviceId, serviceId, characteristicId, value, retryCount + 1);
    }
}

2. 适配Mac Chrome的Web Bluetooth写入特性

Mac端Chrome对writeValue的处理存在差异,可能因设备蓝牙特性属性(如是否支持带响应写入)导致写入未被正确确认,显式指定写入类型:

// 替换原writeValue调用,根据设备特性选择写入类型
await ch.writeValue(new Uint8Array(value), { type: "withResponse" });

注:若设备支持无响应写入,使用"withoutResponse"可减少延迟;若需确保写入成功,优先用"withResponse"。

3. 提升连接状态判断的可靠性

Mac端蓝牙连接状态判断可能存在延迟,不要依赖device.gatt.connected的即时值,主动尝试重连后再重试:

else {
    if (retryCount >= maxRetries) {
        console.error("Max retries reached, failed to connect device");
        return;
    }
    try {
        await device.gatt.connect(); // 主动尝试重新连接设备
    } catch (connectError) {
        console.error("Failed to reconnect device:", connectError);
    }
    await sleep(1000);
    await writeValue(deviceId, serviceId, characteristicId, value, retryCount + 1);
}

4. 避免Blazor按钮重复触发

Mac端Blazor可能存在按钮点击事件重复触发的问题,添加状态锁防止重复调用:

<button @onclick="SendCutCommand">发送切割指令</button>

@code {
    private bool _isSending;

    private async Task SendCutCommand()
    {
        if (_isSending) return;
        _isSending = true;
        try
        {
            await JSRuntime.InvokeVoidAsync("writeValue", deviceId, serviceId, characteristicId, cutCommandValue);
        }
        finally
        {
            _isSending = false;
        }
    }
}

5. 增加日志追踪细节

在Mac端Chrome DevTools中添加更详细的日志,定位问题根源:

console.log(`Write attempt ${retryCount + 1}, device connected: ${device.gatt.connected}`);

内容的提问来源于stack exchange,提问作者user17511401

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:25:27