Web 蓝牙实战指南:三步搞定设备连接与故障排查

别在那儿瞎猜了。

Web Bluetooth API 这东西,看着挺美,真上手一跑,全是坑。耳机连不上、键鼠没反应、IoT 传感器数据断流,这些破事儿我见得太多了。很多人第一反应是去改代码,恨不得把整个协议栈重写一遍。其实大可不必。绝大多数时候,问题根本不在你的逻辑里,而是在浏览器那套繁琐的授权机制或者设备本身的广播策略上。

咱们今天不聊那些虚头巴脑的理论。就只谈怎么把活儿干完。

要把这个连接过程给理顺,你得先把心态放平。别指望它能像原生应用那样丝滑。浏览器为了安全,把这事儿做得极其复杂。你要是想凭借简单的几行代码就来实现设备的无缝接入,那基本上是在做梦。我们需要借助一套标准化的流程,去把那些隐藏在深处的缘由给挖出来。

web bluetooth device scanning dashboard showing available peripherals and signal strength

第一步:把授权这关给闯过去

很多开发者在这一步就卡死了。

点击按钮,没反应。或者弹个框,用户点了允许,后面还是没动静。这时候你开始怀疑人生,觉得是不是浏览器又在搞什么新花样。其实主要原因囊括了用户交互缺失以及上下文环境不对这两个方面。

浏览器不会让你随便就去扫描设备。它强制要求这个动作必须是由用户的明确手势所触发的。也就是说,你不能在页面加载的时候自动去发起扫描请求。你得把这个扫描的动作绑定在一个具体的点击事件上,像是按钮的 click 事件或者是 touchstart 事件。要是你试图在异步回调或者定时器里去调用 requestDevice,那肯定是要失败的。

还得注意这个环境的协议。要是你的站点跑在 HTTP 下,那就别费劲了。Chrome 以及其他主流浏览器早就把非 HTTPS 环境下的蓝牙功能给禁用了。除非你是在 localhost 上进行调试,否则必须得把证书配好,借助 HTTPS 来开展所有的通信工作。这一点经常被忽略,导致很多人在生产环境里怎么也调不通。

有时候你会发现,明明代码写得没问题,权限也点了,可就是搜不到设备。这时候你得去看看设备本身是不是处于可被发现的狀態。有些设备为了省电,会在广播一会儿之后就把自己给藏起来。你得把设备重新上电,或者让它进入配对模式,这样浏览器才能有机会捕捉到它的广播包。

第二步:开展精细化的扫描工作

拿到了权限,接下来就是扫描。

这一步看着简单,实则暗藏玄机。很多人喜欢用通配符,想着能把所有设备都给捞上来。这种做法在测试阶段或许还行,但在实际应用场景当中,简直就是灾难。你会收到一堆乱七八糟的设备信息,里面混杂着各种你不需要的东西,处理起来极其麻烦。

正确的做法是运用过滤器。

你得在 requestDevice 的参数里头,把 filters 选项给配置清楚。你可以依据服务的 UUID 来进行筛选,也可以根据设备的名称前缀来做匹配。比如你只想连接那些支持电池信息服务的设备,那就把 Battery Service 的 UUID 填进去。这样一来,浏览器就会把那些不符合条件的设备直接给过滤掉,只把适宜的设备列表展示给用户。

bluetooth filter configuration interface with uuid selection and name prefix input

这里有个细节特别值得说道说道。

有些厂商为了实现自己的私有协议,会在广播数据里塞一些自定义的服务 UUID。你要是不知道这些 UUID 是个啥,那就很难把设备给筛出来。这时候你就得去翻翻设备的文档,或者借助一些原生的蓝牙调试工具,先把这些关键的标识符给搞清楚。一旦你把这些 UUID 弄明白了,再把它填到过滤条件当中,扫描的效率立马就能得到极大的提升。

还要注意这个接受度的问题。

即便你配好了过滤器,浏览器也不一定会把所有匹配的设备都显示出来。它可能会因为信号强度太弱,或者是设备已经连接到了其他主机,而选择把这个设备给隐藏掉。所以你在进行排查的时候,尽量把测试设备和电脑靠得近一点,减少信号衰减带来的干扰。同时,确保设备没有连接到手机或者其他平板上,避免资源被占用。

第三步:对连接状态进行深度的验证

连上了,不代表就能用了。

这是最容易出现错觉的地方。你以为 device.gatt.connect() 返回了一个对象,万事大吉了。其实这时候连接可能还处于一种半吊子的状态。特别是当网络波动或者设备固件有 bug 的时候,这个连接随时都有可能断开。

你得对这个连接对象进行持续的监控。

不要只是简单地调用一下方法就完事了。你要去监听 gattserverdisconnected 这个事件。一旦触发,那就说明连接断了。这时候你得有一套机制去进行恢复工作,或者是提示用户重新操作。要是你不去处理这个断开的事件,那你的应用就会陷入一种假死的状态,用户点什么都没反应,体验极差。

web bluetooth connection state machine diagram showing connected disconnected and error states

数据传输也是个重灾区。

当你读取特征值(Characteristic)的时候,经常会遇到读不到数据的情况。这通常是因为你没有开启通知(Notify)或者指示(Indicate)。有些服务要求你必须先写入一个特定的配置值,才能开始接收数据流。你要是漏掉了这个步骤,那就只能干等着。

还有这个 MTU(最大传输单元)的问题。

默认的 MTU 往往比较小,传点大文件或者高频数据根本不够用。虽然 Web Bluetooth API 目前对协商 MTU 的支持还比较有限,但你可以在代码里尝试去读取一下当前的 MTU 大小,看看是不是瓶颈所在。要是发现数据包被截断了,那你就得考虑把数据拆分开来发送,或者压缩一下内容,以适应这个受限的通道。

别忘了兼容性这块儿。

别看 Chrome 支持得挺好,其他浏览器可就不一定了。Firefox 和 Safari 对 Web Bluetooth 的支持程度可以说是参差不齐,甚至在某些版本里完全是空缺的。要是你的用户群体比较杂,那就得做好降级方案。不能因为一个浏览器不支持,就让整个功能瘫痪。你可以检测一下 navigator.bluetooth 是否存在,要是没有,那就友好地提示用户换个浏览器试试,或者引导他们使用原生应用。

写在最后

折腾完这一圈,你应该能明白个大概了。

Web Bluetooth 不是银弹。它有着严格的限制,也有着不少让人头疼的边界情况。但只要你按照授权、扫描、验证这三个步骤,一步步地去把问题给剥离出来,大部分故障都是可以被解决的。

别再去盲目地修改代码了。

先拿起手里的在线工具,把浏览器的控制台打开,看看底层的日志到底报了什么错。很多时候,答案就藏在那个不起眼的错误码里头。只有当你真正理解了浏览器是如何去处理这些请求的,你才能在这个充满不确定性的领域当中,找到那条确定的路径。

去吧,把那些连不上的设备都给搞定。

準備ができていますか?それはただの数秒です。

推薦工具

オンラインマイクテスト - 録音とマイクテスト

マイクテスト、マイク検出、録音テスト、インストール不要、プライバシー保護

無料のオンラインマイクテストツール。ワンクリックでマイクに音、エコー、ノイズがあるかどうかを検出します。リアルタイムの波形表示と録音再生をサポートしており、ソフトウェアをダウンロードする必要がなく、プライバシーとセキュリティを保護します。

クリックしてテストを開始します

オンラインカメラテスト - ウェブカメラ/ビデオ検出

カメラテスト、ウェブカメラ検出、ビデオデバッグ、オンライン写真、解像度

カメラが適切に動作しているかどうかをオンラインですばやく確認し、画像の鮮明さ、解像度、フォーカスを確認します。ミラー反転、スクリーンショットの撮影をサポートしており、ビデオ会議の前に必要なデバッグ ツールです。

クリックしてテストを開始します

オンラインGPS測位精度テスト

GPS テスト、測位精度、経度および緯度クエリ、IP 測位、位置許可

現在のデバイスの地理的位置情報を取得し、GPS および IP 測位の精度をテストします。緯度と経度の座標、高度、リアルタイムの位置更新速度を確認します。

クリックしてテストを開始します

環境光センサー(ルクス)検出

光感知、自動明るさ、ルクステスト、センサーデータ、周囲光

デバイスの周囲光センサーの照度データ (ルクス) をリアルタイムで読み取ります。携帯電話やパソコンの自動明るさ調整機能が正常かどうかをテストし、周囲の光の強さを監視してください。

クリックしてテストを開始します

画面タッチテスト - マルチタッチ検出

タッチテスト、画面破損タッチ、マルチタッチ、ジェスチャー検出、画面デッドピクセル

携帯電話やタブレットのマルチタッチの数と応答速度を検出するためのプロフェッショナルな画面タッチ テスト ツールです。線描画テストを使用して、画面の切断、デッド ゾーン、感度の問題のトラブルシューティングを行います。

クリックしてテストを開始します

ビデオデコード能力テスト - 4K/8K再生検出

ビデオデコード、4Kテスト、8Kテスト、フレームロス検出、再生パフォーマンス

ブラウザとデバイスのビデオ デコード パフォーマンスのオンライン テスト。4K/8K HD ビデオ テストをサポートします。再生のフリーズ、フレームドロップ、画面の歪み、オーディオとビデオの同期外れの問題を迅速にトラブルシューティングします。

クリックしてテストを開始します