摘要:可以調用函數并為函數提供配置對象,該對象含有關我們要使用哪個設備,以及都有哪些服務可用的信息。現在就得到了可用于讀寫數據的特性寫數據要寫入數據,我們可以在特性上調用函數,以的形式傳遞想要寫入的值,這是二進制數據的存儲方法。
翻譯:瘋狂的技術宅
原文:https://www.smashingmagazine....
本文首發微信公眾號:jingchengyideng
歡迎關注,每天都給你推送新鮮的前端技術文章
摘要:通過漸進式 Web 應用(Progressive Web Apps)技術,你可以開發成熟的 Web 應用。 得益于大量新規范和新功能,以前需要在本機執行的應用,現在可以基于 Web 實現。 不過迄今為止,與硬件設備的交互仍然是遙不可及。 感謝 WebBluetooth 的出現,現在我們可以開發能夠控制燈光、駕駛汽車甚至是無人機的 PWA。
通過PWA技術,Web 應用越來越和本機應用相差無幾。同時 Web 應用也有其額外的好處,比如隱私和跨平臺兼容性。
傳統的 Web 應用與網絡上服務器的通信機制非常出色。現在 Web 正在向本機應用靠攏,所以我們還需要與本機應用相同的功能。
過去幾年在瀏覽器中實現的新規范和功能的數量是驚人的。我們已經有了處理3D的規范,例如 WebGL 和即將推出的 WebGPU。我們可以通過流式傳輸并生成音頻,來觀看視頻并將網絡攝像頭用作輸入設備。我們還可以使用WebAssembly 以幾乎原生的速度運行代碼。此外,盡管 web 最初只是一種網絡媒體,但是它已經轉向 service workers 的離線支持。
盡管這些功能非常強大,但是還有一個本機應用的專屬領域:與設備進行通信。這是我們長期以來一直試圖解決的問題,也是每個人可能會遇到的問題。Web非常適合與服務器通信,但不適合與設備通信。例如,在網絡中設置路由器時,你可能需要輸入 IP 地址并通過純 HTTP 連接來使用 Web 界面,但是沒有任何安全保護。這不管是從體驗上還是在安全性上都是非常糟糕的。最重要的是,你怎樣才能得到正確的IP地址呢?
當我們嘗試創建一個試圖與設備通信的 PWA 時,HTTP 協議是我們遇到的第一個問題。 PWA 只能只用 HTTPS 協議,而本地設備始終只使用 HTTP 。你還需要一個 HTTPS 證書,并且為了獲得證書,還需要一個帶有域名的公共服務器( 我正在談論本地網絡上無法訪問的設備 )。
因此,對于許多設備來說,你需要使用本機應用來設置并使用它們,因為本機應用不受 Web 平臺的限制,可以為其用戶提供愉快的體驗。但是我并不想下載一個 500 MB 的程序來做到這一點。也許你擁有的設備已經有幾年了,應用程序從來沒有為支持你的新手機做過更新。也許你想使用臺式機或筆記本電腦,而制造商只提供一個移動應用。也不是一個理想的體驗。
WebBluetooth 是一種新規范,已在 Chrome 和 Samsung Internet 中實現,它允許我們通過瀏覽器直接與Bluetooth Low Energy 設備進行通信。 PWA 通過與 WebBluetooth 相結合,可以提供 Web 應用的安全性和便利性,并具有直接與設備通信的能力。
由于通信范圍有限,音頻質量差和配對上存在的問題,藍牙的名聲比較差。但是,幾乎所有這些問題都已成為過去式。 Bluetooth Low Energy 是一種現代規范,除了使用的無線頻段相同外,它和舊的藍牙規范幾乎沒有任何關系。每天有超過 1000 萬臺設備提供藍牙支持,其中包括計算機和手機,還有各種設備,如心率和血糖監測儀,物聯網設備,如燈泡和遙控汽車和無人機等玩具。
無聊的理論部分由于藍牙本身不是一種網絡技術,它使用了一些我們可能不太熟悉的詞匯。 先讓我們看看藍牙是如何工作的和一些涉及到的術語。
每個藍牙設備都是“中央設備”(Central device)或“外圍設備”( Peripheral )。 只有中央設備才能啟動通信,并且只能與外圍設備通信。 中央設備可以是計算機或移動電話。
外圍設備無法啟動通信,只能與中央設備通信。 此外,同一時間外圍設備只能與一個中央設備通信。 外圍設備無法與其他外圍設備通信。
中央設備可以與多個外圍設備通信
中央設備可以同時與多個外圍設備通信,并且可以根據需要對消息進行中繼。所以心率監測器無法與你的燈泡進行通信,但是你可以編寫一個程序,該程序在接收心率的中央設備上運行,如果心率超過某個閾值就將燈變為紅色。
當我們談論 WebBluetooth 時,我們談論的是藍牙規范的一個特定部分,稱為通用屬性配置文件(Generic Attribute Profile),它的縮寫是GATT。 (顯然,GAP這個縮寫已經被占用了。)
在 GATT 的支持下,我們不再談論中央設備和外圍設備,而是客戶端和服務器。你的燈泡是服務器。這可能和你的直覺相違背,但是如果你仔細想想,實際上是有道理的。燈泡提供服務,即光。就像瀏覽器連接到互聯網上的服務器一樣,你的手機或計算機也是連接到燈泡中 GATT 服務器的客戶端。
每個服務器都提供一個或多個服務。其中一些服務正式成為標準的一部分,但你也可以定義自己的服務。比如心率監測器的規范中就定義了官方服務。但是燈泡就不是這樣,而且幾乎每個制造商都在試圖重新發明輪子。每項服務都有一個或多個特征。每個特征都有一個可以讀取或寫入的值。目前,最好將其視為一個對象數組,每個對象都具有值的屬性。
簡化的服務和特征層次結構。
與對象屬性不同,服務和特征不是由字符串標識的。 每個服務和特性都有一個唯一的UUID,長度為16 位或128位。嚴格的說,16 位 UUID 是為官方標準保留的,但幾乎沒有人遵循這一規則。 最后,每個值都是一個字節數組。 藍牙中沒有樣式繁多的數據類型。
親密接觸藍牙燈泡讓我們看一個實際的藍牙設備:Mipow Playbulb Sphere。 你可以用 BLE Scanner 或 nRF Connect 等程序連接到設備并查看其所有服務和特征。 在這種情況下,我正在使用iOS的BLE掃描儀應用程序。
視頻地址:https://player.vimeo.com/vide...
連接燈泡時首先看到的是服務列表。有一些標準化的服務,如設備信息服務和電池。但也有一些自定義服務。我對16 位 UUID 為 0xff0f 的服務特別感興趣。如果你打開此服務,可以看到一長串特征值。我不知道這些特征是做什么用的,因為它們只是由 UUID 識別,而且不幸的是它們可能定制服務的一部分,它們并不是標準化的,制造商沒有提供任何支持文檔。
UUID 為 0xfffc 的第一個特性似乎特別有趣。它的值為四個字節。如果我們將這些字節的值從 0x00000000 改為 0x00ff0000 ,則燈泡變為紅色。將其改為 0x0000ff00 會將燈泡變為綠色,修改為 0x000000ff 則變為藍色。這些是RGB顏色,和 HTML 與 CSS 中使用的十六進制顏色完全對應。
第一個字節有什么作用?好吧,如果我們將值更改為 0xff000000 ,則燈泡會變成白色。燈泡包含四個不同的LED,通過更改這四個字節的值,我們可以創建想要的任何顏色。
WebBluetooth API可以用原生應用來改變燈泡的顏色,這真是太棒了,但是我們怎樣在瀏覽器中做到這一點呢?事實證明,憑借我們剛剛學到的關于藍牙和 GATT 的知識,只需幾行JavaScript就可以改變燈泡的顏色,這要歸功 于WebBluetooth API。
我們來研究一下 WebBluetooth API。
連接到設備我們要做的第一件事就是從瀏覽器連接到設備??梢哉{用函數 navigator.bluetooth.requestDevice() 并為函數提供配置對象,該對象含有關我們要使用哪個設備,以及都有哪些服務可用的信息。
在以下示例中,我們將過濾設備的名稱,因為我們只想查看名稱中包含前綴 PLAYBULB 的設備。我們還指定 0xff0f 作為我們想要使用的服務。由于 requestDevice() 函數返回一個promise,可以等待結果返回。
let device = await navigator.bluetooth.requestDevice({ filters: [ { namePrefix: "PLAYBULB" } ], optionalServices: [ 0xff0f ] });
當我們調用此函數時,會彈出一個窗口,顯示符合過濾規則的設備列表。 現在必須手動選擇我們想要連接的設備。這是出于安全和隱私的需要,并為用戶提供控制的權利。用戶決定是否允許 Web 應用連接到設備,當然還有已經被允許連接的設備。 如果沒有用戶手動選擇設備,Web 應用則無法獲取設備列表或連接。
用戶必須通過選擇設備來手動連接。
在我們訪問設備之后,可以通過調用設備 gatt 屬性上的 connect() 函數連接到 GATT 服務器并等待返回結果。
let server = await device.gatt.connect();
一旦我們連上服務器,就可以調用 getPrimaryService() 并傳遞服務的UUID,然后等待結果返回。
let service = await server.getPrimaryService(0xff0f);
然后使用特性的UUID作為參數調用服務上的 getCharacteristic() 并再次等待結果返回。
現在就得到了可用于讀寫數據的特性:
let characteristic = await service.getCharacteristic(0xfffc);寫數據
要寫入數據,我們可以在特性上調用函數 writeValue() ,以 ArrayBuffer 的形式傳遞想要寫入的值 ,這是二進制數據的存儲方法。 我們不能使用常規數組的原因是常規數組中可以包含各種類型的數據,甚至可以存在空洞。
由于我們無法直接創建或修改 ArrayBuffer,因此應該使用“類型化數組”。 類型化數組種的每個元素總是相同的類型,并且沒有任何漏洞。 在我們的例子中,將使用 Uint8Array,它是一個無符號的整數,因此不能包含任何負數,也它不能包含分數; 它是 8 位的,只能包含 0 到 255 之間的值。換句話說:這個是一個字節數組。
characteristic.writeValue( new Uint8Array([ 0, r, g, b ]) );
我們已經知道這個特殊的燈泡是如何工作的。 必須提供四個字節,每個LED一個。 每個字節的值介于 0 到 255 之間,在這種情況下,我們只想使用紅色,綠色和藍色 LED,因此我們使用值 0 關閉白色LED。
讀數據要讀取燈泡的當前顏色,可以使用 readValue() 函數并等待結果返回。
let value = await characteristic.readValue(); let r = value.getUint8(1); let g = value.getUint8(2); let b = value.getUint8(3);
我們得到的值是 ArrayBuffer 形式的 DataView,它提供了一種從 ArrayBuffer 中獲取數據的方法。 在我們的例子中,可以使用 getUint8() 并以索引作為參數來從數組中提取單個字節。
獲得通知變更最后,還有一種方法可以在設備值發生變化時收到通知。 這對于燈泡來說并不是很有用,但對于心率監測器來說,我們需要不斷收到改變的值,而且并不希望每秒手動輪詢這些值。
characteristic.addEventListener( "characteristicvaluechanged", e => { let r = e.target.value.getUint8(1); let g = e.target.value.getUint8(2); let b = e.target.value.getUint8(3); } ); characteristic.startNotifications();
要在值發生變化時及時獲得回調,必須使用參數 characteristicvaluechanged 和回調函數調用特性上的 addEventListener() 函數。 每當值發生變化時,將使用事件對象作為參數調用回調函數,并且我們可以從事件目標的 value 屬性中獲取數據。 最后,再次從 ArrayBuffer 的 DataView 中提取單個字節。
由于藍牙網絡上的帶寬有限,我們必須通過調用特性上的 startNotifications() 來手動啟動這個通知機制。 否則,網絡將被不必要的數據淹沒。 此外,由于這些設備通常使用電池供電,因此沒有必要的數據通信會影響設備的電池壽命,所以內置無線發射器不需要常開。
視頻地址:https://player.vimeo.com/vide...
結論本文已經覆蓋了 WebBluetooth API 的90%。 只需調用幾個函數并發送 4 個字節,你就可以創建一個控制燈泡顏色的 Web 應用。 如果再添加幾行,你甚至可以控制玩具車或駕駛無人機。 隨著越來越多的藍牙設備進入市場,將產生無窮的可能性。
更多資源Bluetooth.rocks! Demos | (GitHub 上的源代碼)
“Web Bluetooth Specification,” Web藍牙社區
Open GATT Registry 藍牙低功耗設備的GATT非官方文檔。
本文首發微信公眾號:jingchengyideng 歡迎掃描二維碼關注公眾號,每天都給你推送新鮮的前端技術文章歡迎閱讀本專欄其他高贊文章:
12個令人驚嘆的CSS實驗項目
世界頂級公司的前端面試都問些什么
CSS Flexbox 可視化手冊
過節很無聊?還是用 JavaScript 寫一個腦力小游戲吧!
從設計者的角度看 React
CSS粘性定位是怎樣工作的
一步步教你用HTML5 SVG實現動畫效果
程序員30歲前月薪達不到30K,該何去何從
第三方CSS安全嗎?
談談super(props) 的重要性
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101939.html
摘要:藍牙串口通訊實驗目的通過藍牙串口輸出,實現無線藍牙串口調試串口函數介紹返回串口緩沖區中當前剩余的字符個數。只有選中該對象才能,下一頁的哦驅動安裝完成后,在電腦計算機管理,可以查看到硬件藍牙串口了。 ...
摘要:定律在那篇最流行的編程語言能做什么里,我們列舉了在不同領域的使用情況,今天讓我們來詳解一下在物聯網中的應用。這個硬件層決定了物聯網應用比應用更加復雜。這時,我開始關注實現物聯網應用的可能性。 凡是能用JavaScript寫出來的,最終都會用JavaScript寫出來。 —— Atwood定律 在那篇《最流行的編程語言JavaScript能做什么?》里,我們列舉了JavaScript在不...
摘要:定律在那篇最流行的編程語言能做什么里,我們列舉了在不同領域的使用情況,今天讓我們來詳解一下在物聯網中的應用。這個硬件層決定了物聯網應用比應用更加復雜。這時,我開始關注實現物聯網應用的可能性。 凡是能用JavaScript寫出來的,最終都會用JavaScript寫出來。 —— Atwood定律 在那篇《最流行的編程語言JavaScript能做什么?》里,我們列舉了JavaScript在不...
摘要:二模塊原理藍牙模塊的通信示意圖如下兩個設備主控芯片或單片機分別連接各自的藍牙模塊,即將主控芯片與藍牙模塊的串口控制引腳交叉連接。如圖注藍牙模塊自帶轉電路。注博主演示的藍牙模塊雖然不是,但是功能和一樣。 ...
閱讀 3447·2023-04-26 01:45
閱讀 2222·2021-11-23 09:51
閱讀 3638·2021-10-18 13:29
閱讀 3428·2021-09-07 10:12
閱讀 698·2021-08-27 16:24
閱讀 1765·2019-08-30 15:44
閱讀 2192·2019-08-30 15:43
閱讀 2944·2019-08-30 13:11