Web Bluetooth 读写蓝牙串口

亦凉 2022-12-30 07:58 485阅读 0赞

首先参考 通过 Web 控制蓝牙设备:WebBluetooth入门。

HTML 定义触发按钮

www/index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>Web Bluetooth</title>
  7. <script src="js/web-bluetooth.js"></script>
  8. </head>
  9. <body>
  10. <button onclick="sendAndReceive()">Send And Receive!</button>
  11. </body>

navigator.bluetooth.requestDevice 必须在某个用户触发的回调内执行,例如在 button 元素的 onclick 事件中调用。在其它环境下调用将产生错误,比如在 $(document).ready 回调中执行就会报告错误:

Must be handling a user gesture to show a permission request

JS 操作 Web Bluetooth

www/js/web-bluetooth.js

  1. async function sendAndReceive() {
  2. let device = await navigator.bluetooth.requestDevice({
  3. filters: [
  4. {
  5. services: [0xffe0]},
  6. ]
  7. });
  8. let server = await device.gatt.connect();
  9. let service = await server.getPrimaryService(0xffe0);
  10. let characteristic = await service.getCharacteristic(0xffe1);
  11. characteristic.addEventListener(
  12. 'characteristicvaluechanged', e => {
  13. console.log(e.target.value);
  14. }
  15. );
  16. characteristic.startNotifications();
  17. await characteristic.writeValue(
  18. new Uint8Array([50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60])
  19. );
  20. }
  • 如果不清楚 getPrimaryService 的参数,那么可以首先用 getPrimaryServices 函数获取服务的 uuid,注意这个函数后面有个s字母。getPrimaryServices 返回一个服务数组,每个数组元素有 uuid 属性。可以这样操作:server.getPrimaryService(server.getPrimaryServices()[0].uuid)
  • getCharacteristic 也一样,可以用 getCharacteristics 函数获取特性的 uuid,注意s字母。
  • characteristic.readValue() 读取的数据不对,一定要用 characteristic.addEventListener( 'characteristicvaluechanged' 的办法。

Node express 做服务器

httpd.js

  1. #!/usr/bin/env node
  2. const port = 8089;
  3. const express = require('express');
  4. var app = express();
  5. app.use(express.static(__dirname + '/www'));
  6. var https = require('https');
  7. var fs = require('fs');
  8. var options = {
  9. key:fs.readFileSync('./keys/server.key'),
  10. cert:fs.readFileSync('./keys/server.crt')
  11. }
  12. var httpsServer = https.createServer(options, app);
  13. httpsServer.listen(port);
  14. console.log('listening https://localhost:' + port);

MDN 上说 Web Bluetooth 只能用在 HTTPS :

This feature is available only in secure contexts (HTTPS)

用 Chrome 87 实测,如果访问的是 localhost 或 127.0.0.1,那么 HTTP 也是可以的,如果是其它地址,那么必须要用 HTTPS,否则会报告错误:

TypeError: Cannot read property ‘requestDevice’ of undefined

HTTPS 服务需要证书,用下面的脚本生成自签名证书:
keys/gen-crt.sh

  1. #!/bin/sh
  2. # https://www.cnblogs.com/whm-blog/p/9413958.html
  3. # 生成服务器端私钥
  4. openssl genrsa -out server.key 1024
  5. # 生成服务端公钥
  6. openssl rsa -in server.key -pubout -out server.pem
  7. # 生成CA私钥
  8. openssl genrsa -out ca.key 1024
  9. # 生成csr文件
  10. openssl req -new -key ca.key -out ca.csr
  11. # 生成自签名证书
  12. openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
  13. # 生成server.csr文件
  14. openssl req -new -key server.key -out server.csr
  15. # 生成带有ca签名的证书
  16. openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

HTTPS 服务的建立参考 node.js express 启用 https 。

参考资料

  • Web APIs > Bluetooth
  • Chrome extension: function must be called during a user gesture
  • Notification.requestPermission()

发表评论

表情:
评论列表 (有 0 条评论,485人围观)

还没有评论,来说两句吧...

相关阅读