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 被认为不够安全