Web Bluetooth API使用经验分享

703 阅读4分钟

1. Web Bluetooth API是什么?

官方介绍:Web Bluetooth API 提供了与低功耗蓝牙设备进行连接和交互的能力。也就是说,这个WebAPI使得我们可以在WEB应用中同低功耗蓝牙进行交互。

这个API的使用限制是:

  1. 浏览器兼容性Web Bluetooth API
  2. 只能同BLE模式的蓝牙进行交互。所谓BLE,即Bluetooth Low Energy,它的一大核心特性是使用 GATT(Generic Attribute Profile)协议来组织设备的服务和特性。
  3. 只能在安全的上下文中使用,即本地开发环境和https协议下,不支持http协议。

2. 理解GATT

在使用WebBluetoothAPI之前,我们先来简单了解一下GATT。

  • GATT(Generic Attribute Profile) 是蓝牙低功耗(BLE)设备间进行数据交换的核心协议,基于客户端-服务器模型。它通过将设备功能划分为服务(Service)和特性(Characteristic)来组织数据。每个服务包含一个或多个特性,特性包含设备的实际数据(如温度、心率等)。GATT 服务器提供服务和特性,而GATT 客户端则通过读取、写入或订阅特性来与服务器交互。交互流程:

  1. 设备连接:客户端与服务器建立蓝牙连接。
  2. 服务发现:客户端查询服务器的可用服务和特性。
  3. 客户端可以读取或写入特性数据。
  4. 客户端可以订阅通知,以便在特性数据发生变化时接收通知。
  5. 服务器推送通知:当特性数据变化时,服务器通过通知(Notify)或指示(Indicate)将变化信息推送给客户端.(Notify为无确认通知,Indicate为有确认通知)。
  • 简单图示:

037de25e3a5caf00572b75b4076ea7fb.png

3. 使用场景和代码示例

比如医生使用蓝牙血压计为患者测量血压后,需要将数据上传到患者信息管理系统上,这时候就可以使用WebBluetoothAPI和设备直接进行交互。当然交互的前提是需要设备供应商提供的对接协议。对接协议的内容一般包括:设备的服务和特性UUID支持的交互操作(如支持Write和Notify)数据帧格式( 一般我们要根据数据帧的格式来解析原始数据得到我们想要的信息)等等。

假设我从对接文档中得到的信息是,设备的Service UUID:FFB0,设备的Characteristic UUID:FFB4,支持的操作有Notify。具体代码如下:

async function connectToDevice() {
  if (!navigator.bluetooth) {
    console.error("Web Bluetooth API 不支持");
    return;
  }
  try {
    // 请求设备并指定服务 UUID
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ["0xFFB0"] }], // 过滤器,指定我们需要连接的服务 UUID
    });

    console.log("发现设备:", device);

    // 连接到设备
    const server = await device.gatt.connect();

    console.log("连接到 GATT 服务器:", server);

    // 监听蓝牙断开的事件
    device.addEventListener("gattserverdisconnected", () => {
      console.log("设备已断开连接");
      // 可以尝试重连,不过重连感觉意义不大,重连过程中可能会错过通知
    });

    // 获取服务
    const service = await server.getPrimaryService("0xFFB0");

    console.log("获取服务:", service);

    // 获取特性
    const characteristic = await service.getCharacteristic("0xFFB2");

    console.log("获取特性:", characteristic);

    // 先订阅特征的通知
    characteristic.addEventListener("characteristicvaluechanged", (event) => {
      const value = event.target.value;
      console.log("收到通知:", value);
      // 处理通知数据 ...
      // 一般我们要根据数据帧的格式来解析原始数据得到我们想要的信息
      deleteMetadata(value);
    });

    // 再开始接收通知
    await characteristic.startNotifications();
  } catch (error) {
    console.error("连接过程中出现错误:", error);
  }
}

需要注意的是,一定要先添加characteristicvaluechanged事件监听再启动接收通知,避免错过通知消息。

代码中用到的API,详见:Web Bluetooth API

4. 其他问题

使用台式机对接时,由于公司电脑本身没有蓝牙模块,所以使用了一个蓝牙适配器。导致使用Web Bluetooth API连接某个设备时,短暂连接二十几秒后会出现gatt服务断开的情况(很稳定地出现),而使用自带蓝牙模块的笔记本则不会出现这个问题,具体原因问了下AI说是连接协议可能与蓝牙适配器不完全兼容的问题,由于不是这个专业,所以很难找到问题根源,如果有懂行的大佬还请不吝赐教。