一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
上一节提到了蓝牙连接 API,在实际的应用中,除了蓝牙连接,有时会需要有线连接,这种控制方式成为 human interface device,简称 HID,HID 对 USB 输入设备进行了规范的定义,我们可以通过HID 进行相关领域的编程。而在浏览器中,我们现在也可以使用这种能力了。
我们可以通过 navigator.hid 获取一个 hid 对象,通过这个对象我们可以做一系列对 HID 设备进行获取和访问的操作。HID 上面主要有 getDevices 和 requestDevice 两个方法。
requestDevice 和蓝牙连接的 API 很相似,我们可以获取到连接到电脑上的 HID 设备信息,我们可以根据条件进行过滤,这里面主要是使用到了 usagePage 的过滤,它可以区分使用的功能,具体的 usagePage 类型定义与通用的 HID 规范相同,可以在文档中查到。请求设备后浏览器会弹出连接请求,用户操作连接成功后我们就可以拿到设备信息了。
一旦用户通过了 requestDevice 的请求,我们在后续就可以使用 getDevices,来进行设备获取了。除了这两个方法,我们可以监听 connect 和 disconnect 两个事件,这样获取连接状态。
const device = await navigator.hid.requestDevice({filters: []});
拿到了设备信息后,我们就可以传输控制信号来实现控制能力了,这部分同样也是使用二进制的方式来传递的,这里涉及到两个方向的行为,我们可以通过监听 inputreport 事件来获取传入的数据,通过 sendFeatureReport 发送输出的信息,举个例子:
device.addEventListener("inputreport", event => {
const { data, device, reportId } = event;
if (device.productId !== 0x2007 && reportId !== 0x3f) return;
const value = data.getUint8(0);
if (value === 0) return;
const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
console.log(`User pressed button ${someButtons[value]}.`);
});
const reportId = 1;
for (let i = 0; i < 10; i++) {
await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
await waitFor(100);
await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
await waitFor(100);
}
这就是一个简单的 HID 交互程序,涉及到的 HID 专业知识这里不做展开了,最后注意 HID 同样也需要在安全上下文运行。