Web 蓝牙:无法将 BLE 设备与具有实时服务器 VS 代码扩展的移动设备配对
Web Bluetooth: Can't pair BLE device with Mobile Device with Live Server VS Code extension
我是 Web 开发领域的初学者。我想通过网页将 BLE 设备 (NRF52840 DK) 与我的移动设备配对。我测试了一个 Web 蓝牙示例,它在我的 PC 上运行良好,如下图所示:
我的电脑 (Chrome) 与 BLE 设备成功配对
我是通过 VS Code 上流行的扩展 Live Server 完成的。当我尝试使用我的 IP 和端口访问我的手机 (Android) 上的那个页面时,按下按钮没有任何反应。
我的手机 (Chrome) 与 BLE 设备配对失败
有什么我没有考虑到的吗?
这里是 HTML & JS 代码:
<!DOCTYPE html>
<html>
<head>
<title>BLE WebApp</title>
</head>
<body>
<form>
<button>Connect with BLE device</button>
</form>
<script>
var deviceName = 'Nordic_HRM'
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
return false
}
return true
}
function getDeviceInfo() {
let chosenHeartRateService = null;
console.log('Requesting Bluetooth Device...')
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => {
console.log("Getting HR Service…")
return server.getPrimaryService('heart_rate');
})
.then(service => {
chosenHeartRateService = service;
return Promise.all([
service.getCharacteristic('heart_rate_measurement')
.then(handleHeartRateMeasurementCharacteristic),
]);
})
}
function handleHeartRateMeasurementCharacteristic(characteristic) {
return characteristic.startNotifications()
.then(char => {
characteristic.addEventListener('characteristicvaluechanged',
onHeartRateChanged);
});
}
function onHeartRateChanged(event) {
const characteristic = event.target;
console.log(parseHeartRate(characteristic.value));
}
function parseHeartRate(data) {
const flags = data.getUint8(0);
const rate16Bits = flags & 0x1;
const result = {};
let index = 1;
if (rate16Bits) {
result.heartRate = data.getUint16(index, /*littleEndian=*/true);
index += 2;
} else {
result.heartRate = data.getUint8(index);
index += 1;
}
const contactDetected = flags & 0x2;
const contactSensorPresent = flags & 0x4;
if (contactSensorPresent) {
result.contactDetected = !!contactDetected;
}
const energyPresent = flags & 0x8;
if (energyPresent) {
result.energyExpended = data.getUint16(index, /*littleEndian=*/true);
index += 2;
}
const rrIntervalPresent = flags & 0x10;
if (rrIntervalPresent) {
const rrIntervals = [];
for (; index + 1 < data.byteLength; index += 2) {
rrIntervals.push(data.getUint16(index, /*littleEndian=*/true));
}
result.rrIntervals = rrIntervals;
}
return result;
}
document.querySelector('form').addEventListener('submit', function(event) {
event.stopPropagation()
event.preventDefault()
if (isWebBluetoothEnabled()) {
getDeviceInfo()
}
})
</script>
</body>
</html>
我认为您描述的方式不可能。
Web Bluetooth 仅适用于启用了 HTTPS 的页面。出于测试目的,它也适用于本地主机。由于您通过未启用 HTTPS 的 IP 地址访问 Web 应用程序,因此 Web 蓝牙不可用。
https://web.dev/bluetooth/#https-only
您可以通过使用布尔值或其他文本向页面添加文本来测试这一点,这些文本将显示网络蓝牙是否可用。
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
document.getElementById('bluetoothState').innerText = 'Not available'
return false
}
document.getElementById('bluetoothState').innerText = 'Available'
return true
}
使用mkcert
创建证书
用法:
mkcert 127.0.0.1 localhost 0.0.0.0 192.168.0.X
使用生成的文件将其添加到 .vscode 目录中的 settings.json 文件(如果不存在则创建)
{
"liveServer.settings.https": {
"enable": true,
"cert": "/full/path/to/file/192.168.0.108+3.pem",
"key": "/full/path/to/file/192.168.0.108+3-key.pem",
"passphrase": ""
}
}
由于自签名证书的性质,这会产生一次警告,但它会确保 https 的几乎所有功能都能正常工作。
我使用这种方法遇到的问题是 chrome.
在本地设备上安装 PWA 被认为不够安全
我是 Web 开发领域的初学者。我想通过网页将 BLE 设备 (NRF52840 DK) 与我的移动设备配对。我测试了一个 Web 蓝牙示例,它在我的 PC 上运行良好,如下图所示:
我的电脑 (Chrome) 与 BLE 设备成功配对
我是通过 VS Code 上流行的扩展 Live Server 完成的。当我尝试使用我的 IP 和端口访问我的手机 (Android) 上的那个页面时,按下按钮没有任何反应。
我的手机 (Chrome) 与 BLE 设备配对失败
有什么我没有考虑到的吗?
这里是 HTML & JS 代码:
<!DOCTYPE html>
<html>
<head>
<title>BLE WebApp</title>
</head>
<body>
<form>
<button>Connect with BLE device</button>
</form>
<script>
var deviceName = 'Nordic_HRM'
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
return false
}
return true
}
function getDeviceInfo() {
let chosenHeartRateService = null;
console.log('Requesting Bluetooth Device...')
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => {
console.log("Getting HR Service…")
return server.getPrimaryService('heart_rate');
})
.then(service => {
chosenHeartRateService = service;
return Promise.all([
service.getCharacteristic('heart_rate_measurement')
.then(handleHeartRateMeasurementCharacteristic),
]);
})
}
function handleHeartRateMeasurementCharacteristic(characteristic) {
return characteristic.startNotifications()
.then(char => {
characteristic.addEventListener('characteristicvaluechanged',
onHeartRateChanged);
});
}
function onHeartRateChanged(event) {
const characteristic = event.target;
console.log(parseHeartRate(characteristic.value));
}
function parseHeartRate(data) {
const flags = data.getUint8(0);
const rate16Bits = flags & 0x1;
const result = {};
let index = 1;
if (rate16Bits) {
result.heartRate = data.getUint16(index, /*littleEndian=*/true);
index += 2;
} else {
result.heartRate = data.getUint8(index);
index += 1;
}
const contactDetected = flags & 0x2;
const contactSensorPresent = flags & 0x4;
if (contactSensorPresent) {
result.contactDetected = !!contactDetected;
}
const energyPresent = flags & 0x8;
if (energyPresent) {
result.energyExpended = data.getUint16(index, /*littleEndian=*/true);
index += 2;
}
const rrIntervalPresent = flags & 0x10;
if (rrIntervalPresent) {
const rrIntervals = [];
for (; index + 1 < data.byteLength; index += 2) {
rrIntervals.push(data.getUint16(index, /*littleEndian=*/true));
}
result.rrIntervals = rrIntervals;
}
return result;
}
document.querySelector('form').addEventListener('submit', function(event) {
event.stopPropagation()
event.preventDefault()
if (isWebBluetoothEnabled()) {
getDeviceInfo()
}
})
</script>
</body>
</html>
我认为您描述的方式不可能。 Web Bluetooth 仅适用于启用了 HTTPS 的页面。出于测试目的,它也适用于本地主机。由于您通过未启用 HTTPS 的 IP 地址访问 Web 应用程序,因此 Web 蓝牙不可用。
https://web.dev/bluetooth/#https-only
您可以通过使用布尔值或其他文本向页面添加文本来测试这一点,这些文本将显示网络蓝牙是否可用。
function isWebBluetoothEnabled() {
if (!navigator.bluetooth) {
console.log('Web Bluetooth API is not available in this browser!')
document.getElementById('bluetoothState').innerText = 'Not available'
return false
}
document.getElementById('bluetoothState').innerText = 'Available'
return true
}
使用mkcert
创建证书
用法:
mkcert 127.0.0.1 localhost 0.0.0.0 192.168.0.X
使用生成的文件将其添加到 .vscode 目录中的 settings.json 文件(如果不存在则创建)
{
"liveServer.settings.https": {
"enable": true,
"cert": "/full/path/to/file/192.168.0.108+3.pem",
"key": "/full/path/to/file/192.168.0.108+3-key.pem",
"passphrase": ""
}
}
由于自签名证书的性质,这会产生一次警告,但它会确保 https 的几乎所有功能都能正常工作。 我使用这种方法遇到的问题是 chrome.
在本地设备上安装 PWA 被认为不够安全