在网页上通过蓝牙串行

François Beaufort
François Beaufort

Web Bluetooth APIWeb Serial API 分别允许 Web 应用与蓝牙低功耗 (BLE) 设备和串行设备通信。虽然许多 Web 开发者已经在使用这些 API 取得了巨大成功,但对支持蓝牙传统设备的需求也在不断增加。

现在,Web Serial API 支持在桌面版 Chrome 117 中与配对的蓝牙经典设备上的 RFCOMM 服务(包括串行端口配置文件 [SPP])进行通信。这为 Web 开发者和用户都带来了新的可能性。以下是一些可以从中受益的真实设备:

  • Pixel Buds Pro 和其他无线入耳式耳机使用 RFCOMM 来管理音频设置和固件更新。
  • 移动 POS 系统使用蓝牙 SPP 与收据打印机通信。
  • 牲畜 RFID 标签读取器使用蓝牙 SPP 记录动物移动情况。

蓝牙 RFCOMM 协议

让我们重温 90 年代末的音乐。只需将 Palm Pilot 放入底板,即可同步次日的日历。如果您可以改为无线传输,岂不更好?借助这项全新的“蓝牙”技术,您可以摆脱所有这些乱糟糟的电线。无线是未来!只有一个问题,所有现有设备都设计为通过 RS-232 线连接。因此,蓝牙使用射频通信 (RFCOMM) 协议向所有现有软件和硬件提供该接口。

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

Web Serial API 变更

从桌面版 Chrome 117 开始,Web 开发者现在可以使用 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],
});

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

您还可以在调用 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 配套应用是一款全新的 Web 应用,可让用户通过任何具有 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 配套应用的屏幕截图。
Pixel Buds Pro Web 配套应用。

资源

致谢

感谢 Reilly Grant、Thomas Steiner、Ben Morss 和 Vincent Scheib 提供审核意见。