前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在浏览器上访问USB设备

在浏览器上访问USB设备

作者头像
云深无际
发布2020-08-11 17:00:32
9K0
发布2020-08-11 17:00:32
举报
文章被收录于专栏:云深之无迹云深之无迹
如果我说简单明了的“ USB”,您很有可能会立即想到键盘,鼠标,音频,视频和存储设备。没错,但是您会发现其他种类的通用串行总线(USB)设备。

这些非标准USB设备要求硬件供应商编写本机驱动程序和SDK,以便您(开发人员)能够利用它们。遗憾的是,此本地代码历来阻止了Web使用这些设备。这就是创建WebUSB API的原因之一:提供一种将USB设备服务公开到Web的方法。使用此API,硬件制造商将能够为其设备构建跨平台的JavaScript SDK。但是最重要的是,通过将USB引入网络,这将使USB更安全,更易于使用。

让我们看看您对WebUSB API的期望:

  1. 购买USB设备。
  2. 将其插入计算机。
  3. 随即会显示一条通知,并提供访问此设备的正确网站。
  4. 只需单击它。网站在那里,随时可以使用!
  5. 单击以连接,然后USB设备选择器将显示在Chrome中,您可以在其中选择设备。
  6. 多田!

如果没有WebUSB API,此过程将如何?

  • 阅读框,标签或在线搜索,可能最终会在错误的网站上看到。
  • 必须安装本机应用程序。
  • 我的操作系统支持吗?确保下载“正确”的东西。
  • 可怕的操作系统提示弹出窗口,并警告您有关从Internet安装驱动程序/应用程序的信息。
  • 错误的代码会损害整个计算机。该Web 包含故障网站。
  • 只能使用USB设备一次?在Web上,一旦关闭选项卡,该网站就会消失。在计算机上,代码始终存在。

开始之前

本文假定您具有USB工作原理的一些基本知识。如果没有,我建议您在NutShell中读取USB。有关USB的背景信息,请查看官方USB规格。

该WebUSB API在Chrome 61是可用的。

适用于原产地审判

为了从使用该领域的WebUSB API的开发人员那里获得尽可能多的反馈,我们先前已在Chrome 54和Chrome 57中将此功能添加为原始试用。

最新的审判已于2017年9月成功结束。

隐私权与安全性

仅HTTPS

由于此API是网络上新增的强大功能,因此Chrome旨在使其仅可用于安全上下文。这意味着您需要在构建时考虑TLS。

注意:我们非常关注安全性,因此您会注意到新的Web功能需要HTTPS。WebUSB API没什么不同,这也是在您的站点上启动并运行HTTPS的另一个很好的理由。

在开发过程中,您将能够http://localhost使用Chrome Dev Editor 或handy之类的工具与WebUSB进行交互 python -m SimpleHTTPServer,但是要在网站上部署它,则需要在服务器上设置HTTPS。我个人出于演示目的而喜欢GitHub Pages。

要将HTTPS添加到服务器,您需要获取TLS证书并进行设置。请务必查看“ 使用HTTPS 进行安全性”文章,以获取最佳实践。有关信息,您现在可以使用新的证书颁发机构Let's Encrypt获得免费的TLS证书。

需要用户手势

作为一项安全功能,navigator.usb.requestDevice必须通过诸如触摸或鼠标单击之类的用户手势来调用已连接的USB设备 。

功能政策

功能策略是一种机制,允许开发人员有选择地启用和禁用各种浏览器功能和API。可以通过HTTP标头和/或iframe“ allow”属性进行定义。

您可以定义一个功能来控制usb属性是否显示在Navigator对象上,或者如果允许WebUSB,则换句话说。

以下是不允许使用WebUSB的标头策略的示例:

代码语言:javascript
复制
Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com

下面是另一个允许USB的容器策略的示例:

代码语言:javascript
复制
<iframe allowpaymentrequest allow=’usb fullscreen’></iframe>

让我们开始编码

WebUSB API严重依赖JavaScript Promises。如果您不熟悉它们,请查看此出色的 Promises教程。还有一件事,() => {}就是ECMAScript 2015 Arrow函数 -与函数表达式相比,它们的语法更短,并且用词法绑定了this。的值。

存取USB装置

您可以使用或提示用户选择单个连接的USB设备,也可以通过 navigator.usb.requestDevice调用navigator.usb.getDevices获取源可以访问的所有连接的USB设备的列表。

navigator.usb.requestDevice函数接受一个定义为的强制性JavaScript对象filters。这些过滤器用于将任何USB设备与给定的供应商(vendorId)和可选的产品(productId)标识符进行匹配。在 classCodeprotocolCodeserialNumber,和subclassCode键也可以在那里定义为好。

例如,以下是访问已配置为允许起点的已连接Arduino设备的方法。

代码语言:javascript
复制
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] }).then(device => {
  console.log(device.productName);      // "Arduino Micro"
  console.log(device.manufacturerName); // "Arduino LLC"}).catch(error => { console.log(error); });

在您问之前,我没有神奇地得出这个0x2341十六进制数。我只是在此USB ID列表中搜索了“ Arduino”一词。

device以上已兑现承诺中返回的USB 具有有关设备的一些基本但重要的信息,例如受支持的USB版本,最大数据包大小,供应商和产品ID,设备可具有的可能配置数量-基本上, 设备USB描述符

有关信息,如果USB设备宣布支持WebUSB并定义了登录页面URL,则在插入USB设备时,Chrome会显示一个持久通知。单击此通知将打开登录页面。

从那里,您可以简单地调用navigator.usb.getDevices并访问Arduino设备,如下所示。

代码语言:javascript
复制
navigator.usb.getDevices().then(devices => {
  devices.map(device => {
    console.log(device.productName);      // "Arduino Micro"
    console.log(device.manufacturerName); // "Arduino LLC"
  });})

与Arduino USB板交谈

好的,现在让我们看看通过USB端口与WebUSB兼容的Arduino板进行通信有多么容易。请查看https://github.com/webusb/arduino上的说明, 以使WebUSB启用草图。

不用担心,我将介绍本文下文中提到的所有WebUSB设备方法。

代码语言:javascript
复制
var device;

navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] }).then(selectedDevice => {
   device = selectedDevice;
   return device.open(); // Begin a session.
 }).then(() => device.selectConfiguration(1)) // Select configuration #1 for the device..then(() => device.claimInterface(2)) // Request exclusive control over interface #2..then(() => device.controlTransferOut({
    requestType: 'class',
    recipient: 'interface',
    request: 0x22,
    value: 0x01,
    index: 0x02})) // Ready to receive data.then(() => device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5..then(result => {
  let decoder = new TextDecoder();
  console.log('Received: ' + decoder.decode(result.data));}).catch(error => { console.log(error); });

请记住,我们在这里使用的WebUSB库仅实现了一个示例协议(基于标准USB串行协议),制造商可以创建他们想要的任何端点集和类型。对于小型配置命令,控制传输特别好,因为它们具有总线优先级并具有明确定义的结构。

这是已上传到Arduino板的草图。

代码语言:javascript
复制
// Third-party WebUSB Arduino library#include <WebUSB.h>WebUSB WebUSBSerial(1 /* https:// */, "webusb.github.io/arduino/demos");#define Serial WebUSBSerialvoid setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // Wait for serial port to connect.
  }
  Serial.write("WebUSB FTW!");
  Serial.flush();}void loop() {
  // Nothing here for now.}

上面的示例代码中使用的第三方WebUSB Arduino库基本上完成了两件事:

  • 该设备充当WebUSB设备,使Chrome浏览器可以读取目标网页的网址。
  • 它公开了一个WebUSB串行API,您可以使用它重写默认的API。

让我们再次看一下JavaScript代码。一旦我们被device用户选择,device.open只需运行所有特定于平台的步骤即可开始与USB设备的会话。然后,我们必须使用选择一个可用的USB配置device.selectConfiguration。请记住,配置指定了设备的供电方式,最大功耗以及接口数量。在谈论接口时,我们还需要使用独占访问权限,device.claimInterface因为只有在声明接口所有权时,数据才能传输到接口或关联的端点。最后device.controlTransferOut需要调用 以使用适当的命令设置Arduino设备,以通过WebUSB串行API进行通信。

从那里device.transferIn执行批量传输到设备上,以通知主机主机已准备好接收批量数据。然后,使用result包含必须正确解析的DataView 的对象 来实现promise data

对于那些熟悉USB的人来说,所有这些看起来都应该很熟悉。

我想要更多

WebUSB API使您可以与所有USB传输/端点类型进行交互:

  • 通过controlTransferIn(setup, length)和来处理用于向USB设备发送或接收配置或命令参数的CONTROL传输controlTransferOut(setup, data)
  • 用于少量时间敏感数据的INTERRUPT传输的处理方法与transferIn(endpointNumber, length)和和进行BULK传输的处理方法相同 transferOut(endpointNumber, data)
  • 同步传输,用于类似的视频和声音数据的流与处理isochronousTransferIn(endpointNumber, packetLengths)isochronousTransferOut(endpointNumber, data, packetLengths)
  • 批量传输(用于以可靠的方式传输大量非时间敏感数据)由transferIn(endpointNumber, length)和 处理transferOut(endpointNumber, data)

您可能还想看看Mike Tsao的WebLight项目,该项目提供了一个构建示例的示例,该示例构建了一个为WebUSB API设计的USB控制的LED设备(此处不使用Arduino)。您会找到硬件,软件和固件。

提示

通过内部页面chrome://device-log ,可以更轻松地在Chrome中调试USB ,您可以在一个位置查看所有与USB设备相关的事件。

内部页面chrome://usb-internals也很方便,使您可以模拟虚拟WebUSB设备的连接连接和断开连接。这对于无需实际硬件即可进行UI测试非常有用。

在大多数Linux系统上,默认情况下USB设备被映射为只读权限。要允许Chrome打开USB设备,您需要添加新的udev规则。创建一个包含/etc/udev/rules.d/50-yourdevicename.rules以下内容的文件:

代码语言:javascript
复制
SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

这里[yourdevicevendor]2341如果你的设备是例如一个Arduino。 ATTR{idProduct}也可以添加更具体的规则。确保您 user是该plugdev组的成员。然后,只需重新连接设备即可。

下一步是什么

WebUSB API的第二次迭代将关注Shared Worker 和Service Worker 支持。例如,想象一下使用WebUSB API的安全密钥网站,该网站将安装服务工作者以充当中间人来认证用户。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开始之前
    • 适用于原产地审判
    • 隐私权与安全性
      • 仅HTTPS
        • 需要用户手势
          • 功能政策
          • 让我们开始编码
            • 存取USB装置
              • 与Arduino USB板交谈
                • 我想要更多
                • 提示
                • 下一步是什么
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档