首页 > 其他分享 >WebUSB 初体验:让你的设备插上飞翔的翅膀

WebUSB 初体验:让你的设备插上飞翔的翅膀

时间:2024-12-19 14:28:36浏览次数:10  
标签:初体验 const await device console WebUSB 插上 设备

"谁能想到,浏览器居然能直接管 USB?科技这碗饭,越来越难吃了!"

什么是 WebUSB?

WebUSB 是一项让浏览器直接与 USB 设备通信的技术,旨在缩短开发者和设备间的距离。无需安装驱动,无需依赖复杂的桌面软件,直接通过 JavaScript 和 USB 设备交互。是不是听起来很酷?但别着急,这背后还有不少坑等着你跳。

快速上手:连接 USB 设备

以下是 WebUSB 的基本使用流程,使用了现代的 async/await 语法,让代码更清晰易懂。

1. 请求设备连接

navigator.usb.requestDevice() 是一个用于请求用户连接 USB 设备的 API。你可以通过设置 filters 来限制可连接的设备。

const connectToDevice = async () => {
  const filters = [
    { vendorId: 0x1234, productId: 0x5678 } // 根据你的设备填写
  ];

  try {
    // 请求用户选择并授权连接设备
    const device = await navigator.usb.requestDevice({ filters });
    console.log(`连接成功:${device.productName}`);

    // 打开设备的连接
    await device.open();
    console.log('设备已打开');

    // 选择设备的配置编号,通常为 1
    await device.selectConfiguration(1);
    console.log('配置已选择');

    // 声明接口,以便进行数据传输
    await device.claimInterface(0);
    console.log('接口已被声明');

    return device;
  } catch (error) {
    console.error('连接失败:', error);
  }
};

// 示例调用
const device = await connectToDevice();
2. 发送数据

transferOut() 是用于向 USB 设备发送数据的 API。数据通常以 ArrayBufferTypedArray 的形式传递。

const sendData = async (device, data) => {
  try {
    const endpointNumber = 1; // 数据发送的端点编号,需参考设备文档
    const encoder = new TextEncoder();

    // 发送数据到设备的指定端点
    await device.transferOut(endpointNumber, encoder.encode(data));
    console.log('数据已发送:', data);
  } catch (error) {
    console.error('发送数据失败:', error);
  }
};

// 示例调用
await sendData(device, 'Hello, USB!');
3. 接收数据

transferIn() 是用于从 USB 设备接收数据的 API。你需要指定接收的端点编号和数据的最大长度。

const receiveData = async (device) => {
  try {
    const endpointNumber = 1; // 数据接收的端点编号,需参考设备文档

    // 从设备的指定端点接收数据,最大长度为 64 字节
    const result = await device.transferIn(endpointNumber, 64);
    const decoder = new TextDecoder();

    // 将接收到的 ArrayBuffer 数据解码为字符串
    console.log('接收到的数据:', decoder.decode(result.data));
  } catch (error) {
    console.error('接收数据失败:', error);
  }
};

// 示例调用
await receiveData(device);
4. 释放设备

releaseInterface() 用于释放设备的接口。

const releaseDevice = async (device) => {
  try {
    // 释放设备的接口
    await device.releaseInterface(0);
    console.log('接口已释放');

    // 关闭设备连接
    await device.close();
    console.log('设备已关闭');
  } catch (error) {
    console.error('释放设备失败:', error);
  }
};

// 示例调用
await releaseDevice(device);

浏览器兼容性问题

说到 WebUSB,兼容性是避不开的话题。以下是目前主流浏览器的支持情况:

浏览器是否支持 WebUSB 和 WebHID
Chrome
Edge
Firefox否(不支持,开发者请流泪)
Safari否(想都别想)
Opera
友情提示
  • WebUSB 和 WebHID 都只被 Chromium 内核浏览器支持,意味着如果你的用户群体用的是 Firefox 或 Safari,你需要考虑降级方案,比如桌面客户端。

  • 开发前记得检查 Can I Use 网站确认最新兼容性。

WebUSB vs. WebHID:两兄弟的恩怨情仇

WebUSB 和 WebHID 都是让浏览器与硬件交互的技术,但它们各有分工:

特性WebUSBWebHID
用途通用 USB 设备通信专注于人机接口设备
复杂性配置复杂,协议自由度高配置简单,专注特定类型
使用场景自定义设备、工业设备键盘、鼠标、手柄等输入设备

什么时候用 WebUSB?
  • 自定义设备:当你的设备不遵循任何现成标准协议,比如需要与某些传感器或工业设备通信时。

  • 高灵活性场景:当你需要完全掌控设备协议时。

什么时候用 WebHID?
  • 标准人机接口设备:如果你的设备已经符合 HID 标准,比如键盘、鼠标、游戏手柄。

  • 快速开发:HID 协议内置了一些简单的抽象,减少了繁琐的配置工作。

避坑指南

  1. 设备权限问题

    • WebUSB 的设备访问是基于用户授权的,所以每次页面刷新后可能需要重新请求权限。一定要和用户解释清楚:"不是我偷数据,是 USB 设备太严格!"

  2. 数据格式匹配

    • USB 通信对数据格式要求严格。如果设备文档写了用 Uint8Array,你就别用 String,发送错了可是没有撤回的。

  3. 浏览器限制

    • Safari 和 Firefox 的无情拒绝让 WebUSB 和 WebHID 的适用范围大打折扣。如果你的用户群体覆盖这些浏览器,建议提供降级方案,比如桌面客户端。

总结

WebUSB 是一项令人兴奋的技术,但也是一把双刃剑。它可以极大简化设备与用户的交互流程,但也带来了诸如兼容性、权限和复杂性的问题。而 WebHID 作为更专注的技术,为某些特定场景提供了便捷方案。总之,如果你准备跳进 WebUSB 或 WebHID 的坑,那就挽起袖子,用代码说话!

最后,记住:别轻易尝试跟设备讲道理,设备永远是对的!

关注我微信公众号————>花吕观学前端

标签:初体验,const,await,device,console,WebUSB,插上,设备
From: https://blog.csdn.net/Hua_Lvguan/article/details/144584802

相关文章

  • 工作流管理指南:为你的业务插上效率的翅膀!
    在现代企业运营中,随着业务规模的扩大和复杂性的增加,高效的工作流管理成为提高生产力和竞争力的关键环节。无论是流程的设计、实施还是优化,工作流管理都在资源配置、团队协作和结果交付中起到至关重要的作用。本文将深入探讨工作流管理的定义、基本原理、常见挑战及其优化方法,帮助......
  • 01、vue2初体验
    一、Vue程序初体验先不去了解Vue框架的发展历史,Vue框架的特点,Vue的作者,这些对于我们开发来说,没有什么特别的作用,我们先学会基本使用,然后再去详细了解它的特点,就会发现,原来如此。但我们需要指导Vue是一个基于JavaScript(JS)实现的框架,想要使用它,就得先拿到Vue的js文件Vue官网......
  • 软件开发 --- redis 之初体验
    一个键值对(Key-Value)的内存数据库可以用作数据库缓存、消息队列、排行榜等场景。 快速上手Redis默认有16个数据库(索引从0到15),但所有命令默认都会在数据库0中执行,除非你显式地使用SELECT命令来切换到其他数据库。安装  1.数据缓存:快速存取热点数据Redis常......
  • C 语言学习心得:编程世界的初体验与成长
    学习C语言的过程就像是一场充满挑战与惊喜的冒险。从最初接触到它神秘而严谨的语法结构,到逐渐能够运用它构建出具有各种功能的程序,这期间我经历了困惑、沮丧,更收获了满满的成就感,深刻体会到了编程的魅力与艰辛。 C语言简洁而高效的特性犹如一把双刃剑。一方面,它给予了程......
  • 软件开发 --- vue之初体验
    实例就是DOM处理器。一个Vue实例通过el绑定一个根DOM元素,用于管理html视图。通常情况下,Vue推荐使用单一根实例,并通过组件化来管理不同的功能模块。多个Vue实例的做法虽然可以实现,但会让代码变得难以维护和扩展,尤其在复杂的应用中。通常,使用VueRouter和Vuex来管......
  • 实验1 现代C++编程初体验
    实验1:task.cpp1#include<iostream>2#include<string>3#include<vector>4#include<algorithm>5usingnamespacestd;67template<typenameT>8voidoutput(constT&c);910voidtest1();11voidtest2();......
  • 0元购-初体验
    闲来无事想着验证一下支付逻辑漏洞的方法,网上教程一大堆,但是没实践成功,总不确定是不是真正有用的知识。通常支付逻辑漏洞测试方法概况如下:1、直接修改商品的价格2、修改支付状态3、修改商品数量4、重复支付5、越权支付6、线程并发问题随手找一个资产(这次真的随便搜了......
  • 实验1 现代C++编程初体验
    实验任务1代码1//现代C++标准库、算法库体验2//本例用到以下内容:3//1.字符串string,动态数组容器类vector、迭代器4//2.算法库:反转元素次序、旋转元素5//3.函数模板、const引用作为形参67#include<iostream>8#include<string>9......
  • 实验1 现代c++编程初体验
    任务1:task1.cpp1//现代C++标准库、算法库体验2//本例用到以下内容:3//1.字符串string,动态数组容器类vector、迭代器4//2.算法库:反转元素次序、旋转元素5//3.函数模板、const引用作为形参67#include<iostream>8#include<string>......
  • 实验1 现代C++编程初体验
    task1:1//现代C++标准库、算法库体验2//本例用到以下内容:3//1.字符串string,动态数组容器类vector、迭代器4//2.算法库:反转元素次序、旋转元素5//3.函数模板、const引用作为形参67#include<iostream>8#include<string>9#includ......