首先参考 通过 Web 控制蓝牙设备:WebBluetooth入门。
HTML 定义触发按钮
www/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web Bluetooth</title>
<script src="js/web-bluetooth.js"></script>
</head>
<body>
<button onclick="sendAndReceive()">Send And Receive!</button>
</body>
navigator.bluetooth.requestDevice
必须在某个用户触发的回调内执行,例如在 button
元素的 onclick
事件中调用。在其它环境下调用将产生错误:
Must be handling a user gesture to show a permission request
JS 操作 Web Bluetooth
www/js/web-bluetooth.js
async function sendAndReceive() {
let device = await navigator.bluetooth.requestDevice({
filters: [
{services: [0xffe0]},
]
});
let server = await device.gatt.connect();
let service = await server.getPrimaryService(0xffe0);
let characteristic = await service.getCharacteristic(0xffe1);
characteristic.addEventListener(
'characteristicvaluechanged', e => {
console.log(e.target.value);
}
);
characteristic.startNotifications();
await characteristic.writeValue(
new Uint8Array([50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60])
);
}
- 如果不清楚
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
#!/usr/bin/env node
const express = require('express');
const port = 8089;
var app = express();
app.use(express.static(__dirname + '/www'));
app.listen(port);
console.log('listening http://localhost:' + port);
MDN 上说 Web Bluetooth 只能用在 HTTPS ,但 Chrome 87 也支持 HTTP:
This feature is available only in secure contexts (HTTPS)
如果必须要用 HTTPS,那么参考 node.js express 启用 https。
参考资料
- Web APIs > Bluetooth
- Chrome extension: function must be called during a user gesture
- Notification.requestPermission()