Featured image of post Web 蓝牙 API:从浏览器连接硬件Featured image of post Web 蓝牙 API:从浏览器连接硬件

Web 蓝牙 API:从浏览器连接硬件

Web 蓝牙 API 指南,涵盖 GATT、设备发现、服务/特性交互、配对、重新连接、安全性和 IoT 示例。

Web 蓝牙 API 将硬件交互引入浏览器,使 Web 应用程序能够与蓝牙低功耗 (BLE) 设备进行通信。这开辟了物联网用例,例如直接从网页连接心率监视器、温度传感器和智能灯。

网络蓝牙的工作原理

Web 蓝牙通过 GATT(通用属性配置文件)协议运行,该协议是 BLE 通信的标准。在此模型中,BLE 设备充当公开服务和特性的外围设备,而浏览器则充当使用它们的中心。

术语描述示例
服务特色集合电池服务(0x180F)
特点具有属性的数据点电池电量(0x2A19)
描述符有关特征的元数据单位、描述
UUID服务/特性标识符16 位标准或 128 位自定义

Web 蓝牙需要安全上下文(HTTPS 或本地主机)并且必须由用户手势启动。此安全模型可防止后台扫描和未经授权的访问。


设备发现和连接

第一步是从浏览器请求设备:

async function connectDevice() {
  try {
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['battery_service'] }],
      optionalServices: ['environmental_sensing'],
    });

    const server = await device.gatt.connect();
    console.log('Connected to:', device.name);
    return server;
  } catch (error) {
    console.error('Connection failed:', error);
  }
}

filters 参数控制哪些设备出现在浏览器选择器中。使用 namenamePrefixservices 缩小结果范围。 optionalServices 授予对非广告服务的访问权限。


读取和写入数据

连接后,访问服务和特征以交换数据:

async function readBatteryLevel(server) {
  const service = await server.getPrimaryService('battery_service');
  const characteristic = await service.getCharacteristic('battery_level');
  const value = await characteristic.readValue();
  return value.getUint8(0);
}

async function writeToCharacteristic(server, serviceUUID, charUUID, data) {
  const service = await server.getPrimaryService(serviceUUID);
  const characteristic = await service.getCharacteristic(charUUID);
  await characteristic.writeValue(new TextEncoder().encode(data));
}

如需实时数据,请订阅通知:

const characteristic = await service.getCharacteristic('heart_rate_measurement');
await characteristic.startNotifications();
characteristic.addEventListener('characteristicvaluechanged', (event) => {
  const value = event.target.value;
  // Parse heart rate data from ArrayBuffer
});

重连和连接管理

优雅地处理断开连接并实现重新连接:

const device = await navigator.bluetooth.requestDevice({ filters: [...] });

device.addEventListener('gattserverdisconnected', () => {
  console.log('Device disconnected, attempting reconnect...');
  setTimeout(async () => {
    if (device.gatt.connected) return;
    await device.gatt.connect();
  }, 1000);
});

await device.gatt.connect();

使用 device.watchAdvertisements() 检测附近的设备,从而启用位置感知功能。


安全考虑

网络蓝牙在多个层面上加强安全性。安全上下文要求 (HTTPS) 确保加密传输。用户手势要求可防止未经授权的扫描。配对可能涉及通过密钥输入或数字比较进行身份验证,具体取决于设备功能。

用户之前允许的设备可以通过 navigator.bluetooth.getDevices() 访问,但浏览器在未经用户明确同意的情况下绝不会公开设备。


限制和替代方案

Web 蓝牙有重要的局限性:它仅支持 BLE(不是经典蓝牙),在移动浏览器上没有后台扫描,并且 iOS Safari 支持仍处于实验阶段。有效范围约为 10-30 米,每个数据包的有效负载限制约为 20 字节。

对于超出 Web 蓝牙功能的场景,请考虑 Web Serial(用于串行端口通信)、Web USB 或通过 WebSocket 桥接的本机配套应用程序。


Web 蓝牙 API 支持与物理世界交互的新型 Web 应用程序。从读取传感器数据或接收通知等简单模式开始,然后进行双向通信和绑定以实现更高级的用例。