在网页上通过蓝牙串行

François Beaufort
François Beaufort

借助 Web Bluetooth APIWeb Serial API,Web 应用可分别与蓝牙低功耗 (BLE) 设备和串行设备进行通信。尽管许多 Web 开发者已经在使用这些 API 并取得了巨大成功,但对标准蓝牙设备的支持需求也在不断增长。

现在,Web Serial API 支持与已配对的传统蓝牙设备(包括桌面设备 Chrome 117 中的串行端口配置文件 (SPP))上的 RFCOMM 服务通信。这为 Web 开发者和用户等都开辟了新的可能性。下面列举了一些现实设备也可以受益于此:

  • Pixel Buds Pro 和其他无线入耳式耳机使用 RFCOMM 管理音频设置和固件更新。
  • 移动销售终端系统使用蓝牙 SPP 与收据打印机进行通信。
  • 家畜 RFID 读卡器使用蓝牙 SPP 记录动物的活动。

蓝牙 RFCOMM 协议

回到 90 年代后期。您只需将 Palm Pilot 放入充电座,即可同步第二天的日历。如果您可以通过无线方式完成这项工作,岂不是很棒?借助这项新的“蓝牙”技术,您可以摆脱所有这些杂乱的电源线。无线就是未来!但存在一个问题,现有的一切都设计为连接 RS-232 线。因此,蓝牙使用射频通信 (RFCOMM) 协议向所有现有软件和硬件提供该接口。

即便在今天,RFCOMM 服务仍广泛应用于新硬件和现有硬件。它可满足蓝牙低功耗目前未满足的特定延迟时间和带宽要求。因此,我们开发了 Web Serial(用于连接串行设备的 API)和蓝牙之间的集成,以便在制造商最终迁移到低功耗蓝牙以及开发者可以使用 Web Bluetooth API 之前访问这些旧版 RFCOMM 服务。

Web Serial API 变更

从桌面版 Chrome 117 开始,网络开发者现在可以使用 Web Serial API 通过 RFCOMM 服务与配对的传统蓝牙设备可靠地通信。这得益于对 Web Serial API 的以下更新:

  • 现在,Chrome 会枚举使用标准化蓝牙传统串行端口配置文件公开串行接口的配对蓝牙设备。
  • 现在,即使操作系统尚未专门通过模拟串行端口创建设备节点,Chrome 也可以与串行接口通信。
  • 现在,Chrome 可以与公开了 RFCOMM 串行接口的非串行端口服务通信(请参阅非标准服务类 ID)。

如需了解如何使用 Web Serial API,请参阅在串行端口中读取和写入数据一文。本文假定您具备蓝牙方面的基础知识,并重点介绍通过蓝牙技术的串行功能变更。

在不指定任何过滤器的情况下,调用 navigator.serial.requestPort() 允许用户选择非蓝牙串行端口、已映射的蓝牙串行端口,以及标准化蓝牙传统串行端口配置文件提供的任何未映射串行端口。

// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();

虽然大多数设备都通过标准化蓝牙传统串行端口配置文件公开基于 SPP 的通信,但有些设备使用基于 RFCOMM 的自定义服务。这些设备的服务类 ID 不在标准蓝牙 UUID 范围内。

您需要将 allowedBluetoothServiceClassIds 列表传递给 navigator.serial.requestPort() 才能访问这些基于 RFCOMM 的自定义服务,如以下示例所示。

const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";

// Prompt user to select any serial port.
// Access to the custom Bluetooth RFCOMM service above will be allowed.
const port = await navigator.serial.requestPort({
  allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
});

请注意,所有使用蓝牙 SIG 基本 UUID(即以“-0000-1000-8000-00805f9b34fb”结尾的 UUID)的所有服务类 ID 均被屏蔽,但串行端口配置文件 ID 除外,因为 Chrome 不支持音频和视频等传统蓝牙服务。

您也可以在调用 navigator.serial.requestPort() 时使用 bluetoothServiceClassId 过滤器键,以提示用户列出由服务类 ID 标识的已过滤蓝牙串行端口。请参见下面的示例。

const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";

// Prompt the user to select Bluetooth serial ports with
// the custom Bluetooth RFCOMM service above.
const port = await navigator.serial.requestPort({
  allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
  filters: [{ bluetoothServiceClassId: myBluetoothServiceUuid }],
});

如果该串行端口是蓝牙设备的一部分,则通过调用 port.getInfo() 返回的串行端口信息中会提供一个新的 bluetoothServiceClassId 密钥,该密钥包含与该端口连接的 RFCOMM 通道关联的服务类 ID。如果已映射串行端口,则会返回短格式“00001101-0000-1000-8000-00805f9b34fb”或 0x1101。

const { bluetoothServiceClassId } = port.getInfo();

用例示例:控制 Pixel Buds Pro

Pixel Buds Pro Web Companion 应用是一款新的 Web 应用,可让用户通过带有网络浏览器的任何设备控制其 Pixel Buds Pro。它使用渐进式 Web 应用技术构建而成,可提供即时加载体验,并可选择性地与其他操作系统应用一起安装。

该应用使用 Web Serial API 与 Pixel Buds Pro 通信。这样一来,用户便可以控制 Pixel Buds Pro 上的各种设置,例如主动降噪、均衡器、入耳检测和固件更新。

如要试用 Pixel Buds Pro Web 配套应用,请在 ChromeOS 设备(即将支持其他平台)上访问 mypixelbuds.google.com

Pixel Buds Pro Web Companion 应用的屏幕截图。
Pixel Buds Pro Web Companion 应用。

资源

致谢

感谢 Reilly Grant、Thomas Steiner、Ben Morss 和 Vincent Scheib 提供的评价。 主打图片,由 Mika Baumeister 制作,在 Unsplash 网站上。