网站/PWA中使用JavaScript维持BLE连接存活,避免重复触发设备选择弹窗的技术咨询
保持BLE会话内连接复用的解决方案
嘿,作为编程新手遇到这个问题太正常啦!你现在的代码每次调用readData()都会从头发起设备请求、建立连接,这就是为啥每次操作都要弹设备选择框的原因。咱们只需要把蓝牙设备和GATT连接对象持久化保存下来,在会话期间(浏览器关闭前)复用它们就行,具体方案如下:
核心思路
把蓝牙设备、GATT服务器这些关键对象存在全局变量里,后续操作优先复用已有的连接,只有在连接不存在/断开时才重新发起请求。
修改后的代码示例
// 全局变量保存会话内的蓝牙连接对象 let bluetoothDevice = null; let gattServer = null; const serviceUuid = "你的服务UUID"; const characterUuid = "你的读取特征UUID"; async function connectToDevice() { // 如果已有活跃连接,直接返回现有服务器 if (gattServer && gattServer.connected) { return gattServer; } try { // 无连接时才请求设备 const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [serviceUuid] }], // 允许访问指定服务,后续操作无需重复授权 optionalServices: [serviceUuid] }); // 监听连接断开事件,方便后续处理重连 device.addEventListener('gattserverdisconnected', onDisconnected); const server = await device.gatt.connect(); // 保存对象到全局变量,供后续操作复用 bluetoothDevice = device; gattServer = server; return server; } catch (error) { console.error('连接出错:', error); throw error; } } // 连接断开时的处理函数 function onDisconnected() { console.log('BLE连接已断开'); gattServer = null; // 如需自动重连,可在此处调用connectToDevice() } async function readData() { try { const server = await connectToDevice(); const service = await server.getPrimaryService(serviceUuid); const characteristic = await service.getCharacteristic(characterUuid); const result = await characteristic.readValue(); const decodedResult = decodeValues(result); document.getElementById("output").innerHTML = decodedResult; } catch (error) { console.error('读取数据出错:', error); } } // 新增写入数据函数,复用同一连接无需重新选设备 async function writeData(value) { try { const server = await connectToDevice(); const service = await server.getPrimaryService(serviceUuid); // 替换为你需要写入的特征UUID const writeCharacteristic = await service.getCharacteristic("你的写入特征UUID"); // 根据设备要求转换数据格式,这里以Uint8Array为例 const data = new Uint8Array([value]); await writeCharacteristic.writeValue(data); console.log('数据写入成功'); } catch (error) { console.error('写入数据出错:', error); } }
关键细节说明
- 连接复用:
connectToDevice()函数会先检查是否有活跃连接,只有在无连接时才弹出设备选择框,彻底解决重复弹框的问题。 - 状态监听:通过
gattserverdisconnected事件实时监控连接状态,断开后清空变量,下次操作会自动触发重连流程。 - 异步优化:改用
async/await替代链式then,代码逻辑更直观,新手也能轻松理清执行流程。
这样不管你点击读取还是写入按钮,只要会话内连接保持活跃,就不会再出现烦人的设备选择弹窗啦~
内容的提问来源于stack exchange,提问作者Giri Priyadarshan
相关产品推荐
相关产品推荐

