WebBluetooth API: Web端蓝牙打印的开始

6,050 阅读3分钟

WebBluetooth API: 允许网站通过GATT(Generic Attribute Profile)与附近的用户选择的蓝牙设备以安全和保护隐私的方式进行通信,因此我们可以使用它和打印机以及其他具有蓝牙功能的设置进行通信。接下来就让我们看一下它如何与打印机通信。

WebBluetooth API 只能在 HTTPS 或 localhost 环境下运行。目前是实验性的技术,目前只有chrome支持

获取并链接蓝牙设备

蓝牙接口挂载在navigator.bluetooth接口。它可以通过Bluetooth.requestDevice(options)方法返回一个具有指定选项的BluetoothDevice对象的Promise。如果没有选择器UI,该方法会返回第一个符合标准的设备。options参数包括filters,optionalServices,acceptAllDevices;

const options = {
  filters: [
    {services: ['heart_rate']}, // 标准心率服务
    {services: [0x1802, 0x1803]}, // 两个16位服务ID
    {services: ['c48e6067-5295-48d3-8d5c-0395f61792b1']}, // 一个专有的128位UUID服务ID
    {name: 'ExampleName'}, // 名称为 "ExampleName "的蓝牙设备
    {namePrefix: 'Prefix'} // 名称为 "Prefix " 开头的蓝牙设备
  ],
  optionalServices: ['battery_service'], // 接收服务ids;不会添加任何设备,但它确实会影响网站可以从用户选择的设备中使用哪些服务。
  // acceptAllDevices: true // 设置为 true 时忽略所有的过滤器,它将只能使用optionalServices中列出的服务。
}
navigator.bluetooth.requestDevice(options)
.then(device => {
  // 连接到GATT服务器...
  return device.gatt.connect()
})
.then(async server => {
  // 通过服务的uuid链接服务 必须是小写的 专有的128位UUID服务ID
  return await server.getPrimaryService(serviceID)
})
.then(async service => {
  // 再通过特性的服务id,获取可读写数据的特性
  return await service.getCharacteristic(characteristicServiceID)
})
.catch(error => {
  console.log(error)
})

serviceID, characteristicServiceID 必须是小写的专有的128位UUID服务ID

ServiceId, characteristicServiceID 可以通过蓝牙调试助手App获得

ServiceId还可以通过:chrome://bluetooth-internals/#devices 点击开始扫描获得

数据传递

当我们获取到可读写数据特性时,就可以通过 writeValue()向蓝牙服务发送数据,始终返回一个promise。数据包必须是ArrayBuffer格式。

const characteristic = await service.getCharacteristic(characteristicServiceID)
characteristic.writeValue(buffer).then(res => {}).catch(e => {})

每次只能向characteristic写入512字节的数据,当大于512字节数据时需要以512字节的批次发送数据

let index  = 0
const data = ArrayBuffer(Length)
function send (resolve, reject) {
 if (index + 512 < data.length) {
   characteristic.writeValue(data.slice(index, index + 512)).then(() => { 
     index += 512 
     send(resolve, reject);                                    
   })                                                                          
   .catch(error => reject(error));                                             
 } else {                                                                    
   // 发送剩余的字节                                                      
   if (index < data.length) {                     
     characteristic.writeValue(data.slice(index, data.length)).then(() => { 
     resolve();                                                                  
   })                                                                          
   .catch(error => reject(error));                                             
  }
}

到这里就可以开始和打印机通信,打印相应的数据。

总结

以上就是连接蓝牙的功能内容。但是打印最麻烦的还是对接打印机。每个打印机的格式都有不同就不赘述。其中生成AarryBuffer最好一次生成,不要批次生成。主要还是看打印机的性能。如有错漏,请大家指正。

探索总会发现惊喜。

参考文档

  1. 通用标准服务
  2. WebBluetoothCG
  3. 兼容性