一份关于使用 JavaScript 中的 WebHID API 发现人机接口设备 (HID) 并与之交互的全面指南。学习设备枚举、筛选和连接的最佳实践。
前端 WebHID 设备枚举:使用 JavaScript 发现已连接的设备
WebHID API 释放了 Web 应用程序直接与各种人机接口设备 (HID) 通信的潜力,而这些设备通常只能由原生应用程序访问。这为创造与游戏控制器、自定义输入设备、科学仪器等专用硬件交互的创新 Web 体验开辟了激动人心的可能性。本综合指南深入探讨了设备枚举的核心概念,这是与所需 HID 设备建立连接的关键第一步。
什么是 WebHID API?
WebHID API 允许 Web 应用程序访问人机接口设备。这些设备涵盖了广泛的类别,包括:
- 游戏控制器:操纵杆、游戏手柄、赛车方向盘
- 输入设备:键盘、鼠标、轨迹球
- 工业控制:专用控制面板、传感器接口
- 科学仪器:数据采集设备、测量工具
- 自定义硬件:为特定目的创建的定制输入设备
与提供有限 HID 支持的旧版浏览器 API 不同,WebHID API 提供了对 HID 设备的直接访问,使开发人员能够创建更丰富、更具交互性的 Web 应用程序。想象一下,在远程实验室中控制机械臂,使用自定义输入设备操作 3D 模型,或在基于 Web 的仪表板中直接接收传感器数据——所有这些都在浏览器内完成。
理解 HID 设备枚举
在与 HID 设备交互之前,您的 Web 应用程序需要发现哪些设备已连接到用户的系统。这个过程称为设备枚举。WebHID API 提供了一种机制,可以根据供应商 ID (VID) 和产品 ID (PID) 或使用更广泛的筛选器来请求访问特定的 HID 设备。
该过程通常包括以下步骤:
- 请求设备访问:Web 应用程序使用
navigator.hid.requestDevice()提示用户选择一个 HID 设备。 - 筛选设备:您可以指定筛选器以缩小呈现给用户的设备列表。这些筛选器基于设备的 VID 和 PID。
- 处理设备选择:用户从列表中选择一个设备。
- 打开设备:应用程序打开与所选设备的连接。
- 数据传输:一旦建立连接,应用程序就可以从设备发送和接收数据。
设备枚举分步指南
1. 使用筛选器请求设备访问
navigator.hid.requestDevice() 方法是请求访问 HID 设备的入口点。它接受一个可选的 `filters` 参数,这是一个对象数组,用于指定您想要查找的设备的 VID 和 PID。
以下是如何请求访问具有特定 VID 和 PID 的设备的示例:
async function requestHIDDevice() {
try {
const devices = await navigator.hid.requestDevice({
filters: [
{
vendorId: 0x1234, // 替换为您的设备的供应商 ID
productId: 0x5678 // 替换为您的设备的产品 ID
},
// 如果需要,为其他设备添加更多筛选器
]
});
if (devices.length > 0) {
const device = devices[0]; // 使用第一个选择的设备
console.log("HID Device Found:", device);
// 打开设备并开始通信
await openHIDDevice(device);
} else {
console.log("No HID device selected.");
}
} catch (error) {
console.error("Error requesting HID device:", error);
}
}
// 示例用法(例如,由按钮点击触发):
document.getElementById('requestButton').addEventListener('click', requestHIDDevice);
重要注意事项:
- 供应商 ID (VID) 和产品 ID (PID):这些是分配给 USB 和蓝牙设备的唯一标识符。您需要从制造商的文档中或使用系统工具(例如,Windows 上的设备管理器、macOS 上的系统信息或 Linux 上的 `lsusb`)获取目标设备的 VID 和 PID。
- 用户同意:
requestDevice()方法会向用户显示一个由浏览器控制的权限提示,允许他们选择授予访问权限的 HID 设备。这是一项至关重要的安全措施,以防止恶意网站在未经用户同意的情况下访问敏感硬件。 - 多个筛选器:您可以在 `filters` 数组中包含多个筛选器,以请求访问具有不同 VID 和 PID 的设备。如果您的应用程序支持多种硬件配置,这将非常有用。
2. 获取设备信息
用户选择设备后,requestDevice() 方法会返回一个 HIDDevice 对象数组。每个 HIDDevice 对象都包含有关设备的信息,例如其 VID、PID、usagePage、usage 和 collections。您可以使用这些信息来进一步识别和配置设备。
async function openHIDDevice(device) {
try {
await device.open();
console.log("HID Device Opened:", device.productName);
// 监听输入报告
device.addEventListener("inputreport", event => {
const { data, reportId } = event;
const uint8Array = new Uint8Array(data.buffer);
console.log(`Received input report ${reportId}:`, uint8Array);
// 处理输入报告数据
});
device.addEventListener("disconnect", event => {
console.log("HID Device Disconnected:", device.productName);
// 处理设备断开连接
});
} catch (error) {
console.error("Error opening HID device:", error);
}
}
设备属性:
vendorId:设备的供应商 ID。productId:设备的产品 ID。productName:产品的可读名称。collections:一个HIDCollectionInfo对象数组,描述设备的 HID 集合(报告、功能等)。这可能非常复杂,仅在处理复杂设备时需要。
3. 处理设备连接和断开
WebHID API 提供事件来通知您的应用程序设备何时连接或断开。您可以监听 navigator.hid 对象上的 connect 和 disconnect 事件。
navigator.hid.addEventListener("connect", event => {
const device = event.device;
console.log("HID Device Connected:", device);
// 处理设备连接(例如,重新打开设备)
});
navigator.hid.addEventListener("disconnect", event => {
const device = event.device;
console.log("HID Device Disconnected:", device);
// 处理设备断开连接(例如,清理资源)
});
连接管理最佳实践:
- 连接时重新枚举:当设备连接时,重新枚举设备通常是一个好习惯,以确保您的应用程序拥有最新的列表。
- 断开时清理资源:当设备断开时,释放与其关联的任何资源(例如,关闭设备连接,移除事件监听器)。
- 错误处理:实施强大的错误处理,以优雅地处理设备连接失败或意外断开的情况。
高级设备筛选技术
除了基本的 VID 和 PID 筛选外,WebHID API 还提供了更高级的技术来定位特定设备。这在处理具有多个接口或功能的设备时特别有用。
1. 按使用页 (Usage Page) 和用途 (Usage) 筛选
HID 设备被组织成*使用页 (usage pages)* 和*用途 (usages)*,它们定义了设备提供的功能类型。例如,键盘属于“通用桌面”使用页,并具有“键盘”用途。您可以根据设备的使用页和用途来筛选设备,以定位特定的设备类型。
async function requestSpecificKeyboard() {
try {
const devices = await navigator.hid.requestDevice({
filters: [
{
usagePage: 0x01, // 通用桌面页
usage: 0x06 // 键盘用途
}
]
});
// ... (处理设备的其余代码)
} catch (error) {
console.error("Error requesting HID device:", error);
}
}
查找使用页和用途值:
- HID 用途表:官方的 HID 用途表(由 USB 实施者论坛发布)定义了各种设备类型的标准化使用页和用途。
- 设备文档:设备制造商的文档可能会指定其设备的使用页和用途值。
- HID 报告描述符:对于高级场景,您可以分析设备的 HID 报告描述符以确定其支持的使用页和用途。
2. 处理多个接口
一些 HID 设备会暴露多个接口,每个接口都有自己的一套功能。WebHID API 将每个接口视为一个独立的 HID 设备。要访问特定接口,您可能需要将 VID/PID 筛选与使用页/用途筛选相结合,以定位所需的接口。
实际示例和用例
1. 构建自定义游戏控制器界面
想象一下,您正在构建一个基于 Web 的游戏,并希望支持自定义游戏控制器。您可以使用 WebHID API 直接从控制器的按钮、操纵杆和其他控件中读取输入。这使您可以创建高度响应和沉浸式的游戏体验。
2. 创建一个基于 Web 的 MIDI 控制器
音乐家和音频工程师可以从与数字音频工作站 (DAW) 或合成器交互的基于 Web 的 MIDI 控制器中受益。WebHID API 使您能够构建可直接在浏览器中发送和接收 MIDI 消息的自定义 MIDI 控制器。
3. 与科学仪器交互
研究人员和科学家可以使用 WebHID API 与科学仪器(如数据采集设备、传感器和测量工具)进行接口。这使他们能够直接在基于 Web 的仪表板或分析工具中收集和分析数据。
4. 无障碍应用
WebHID 为创建辅助技术提供了机会。例如,可以为有运动障碍的用户将专门的输入设备直接集成到 Web 应用程序中,提供更定制化和无障碍的体验。全球性的例子可能包括集成专门的眼动追踪设备以实现免提导航,或为跨不同语言和输入法的单键切换访问提供可定制的按钮阵列。
跨浏览器兼容性和安全注意事项
1. 浏览器支持
WebHID API 目前在基于 Chromium 的浏览器(Chrome、Edge、Opera)中受支持,并且正在为其他浏览器进行开发。在您的应用程序中实施 WebHID API 之前,检查浏览器兼容性并为不支持该 API 的浏览器提供回退机制非常重要。
2. 安全注意事项
WebHID API 在设计时考虑了安全性。在允许 Web 应用程序访问 HID 设备之前,浏览器会提示用户授予权限。这可以防止恶意网站在未经用户同意的情况下访问敏感硬件。此外,WebHID API 在浏览器的安全沙箱内运行,限制了应用程序对系统资源的访问。
- 仅限 HTTPS:与其他强大的 Web API 一样,WebHID 需要在安全上下文 (HTTPS) 中运行。
- 用户手势:请求设备访问通常需要用户手势(例如,按钮点击)以防止未经请求的访问请求。
- Permissions API:Permissions API 可用于查询和管理 WebHID 权限。
常见问题排查
1. 找不到设备
如果您的应用程序找不到 HID 设备,请仔细检查 VID 和 PID。确保它们与设备的实际标识符匹配。此外,请验证设备是否已正确连接并被操作系统识别。
2. 权限被拒绝
如果用户拒绝访问 HID 设备的权限,您的应用程序将无法与其通信。通过向用户显示一条消息并解释为什么需要访问权限来优雅地处理这种情况。考虑为用户提供与您的应用程序交互的替代方式。
3. 数据格式问题
HID 设备通常使用自定义数据格式来发送和接收数据。您需要了解设备的数据格式,并在您的应用程序中实现适当的解析和序列化逻辑。有关数据格式的信息,请查阅设备制造商的文档。
结论
WebHID API 使 Web 开发人员能够创建直接与人机接口设备通信的创新和交互式 Web 应用程序。通过理解设备枚举、筛选和连接管理的原则,您可以释放 WebHID API 的全部潜力,并创造引人入胜的用户体验。拥抱 WebHID 的力量,将 Web 与物理世界连接起来,为全球的创造力、生产力和无障碍性培育新的可能性。