本文是 Uber 的客戶端工程師團隊講述瞭如何開發最新版本司機端系列文章中的第七篇,該系列代號 Carbon ,是咱們共享出行業務的核心。包括其它功能在內,Uber 司機端使得超過 300 萬名司機能夠查看費用、里程以及收益狀況。2017 年咱們結合司機的反饋開始對司機端進行從新設計,並在 2018 年 9 月份啓動了該項目。html
因爲技術和物理因素,接駕對於乘客和司機來講都是一個特別難的痛點。技術方面,咱們須要司乘兩端達成相對的同步。物理方面,例如在一個夜間擁擠的街道,司機、乘客將彼此很難找尋到對方。對於平臺來講,幫助乘客輕鬆辨識車輛是成功開啓愉快行程的關鍵。react
指示燈 是咱們應用程序進入現實世界的一種擴展,這是一個給司乘 2 方提供直觀顏色匹配的設備,乘客能夠選擇光譜中的任何顏色進行設置。在黑暗和暴風雨的夜晚,選擇一種顏色照亮司機車輛的擋風玻璃,可讓你更快速方便的找尋到車輛。事實上推進這種體驗的工程設計並不簡單。接下來讓咱們深刻了解一下如何利用咱們的 APP 實現這種體驗。編程
乘客經過指示燈功能來選擇一種顏色,而後將其傳輸給汽車上的指示燈設備,這樣乘客就能夠快速方便的知道哪輛車是來接他的。後端
指示燈的大部分功能是在咱們司機端 APP 上使用。實現須要使用 2 組資源:Beacon SDK:負責經過藍牙跟指示燈設備進行通訊。RIBs架構 中的一系列功能模塊利用 Beacon SDK 實現司機端的功能。安全
Beacon SDK 幾乎實現了指示燈設備的全部用戶體驗功能,它利用藍牙實現了司機端 APP 和指示燈設備之間鏈接跟數據溝通的功能。在設計 Beacon SDK 時,咱們遵循了三個原理:服務器
由於 Uber 的移動端架構是跨平臺的,同時支持 iOS 跟安卓設備,因此 Beacon SDK 的架構設計也必須是跨平臺的。在跨平臺方面以後,咱們能夠更快速的迭代並提供給其餘團隊更方便的接入方式。網絡
SDK 開發最關鍵的原則是去掉 SDK 對應用的依賴。隨着咱們逐步開發新司機端 APP,這點顯得尤爲重要。SDK 的獨立性使得咱們在新舊司機端 APP 同時開發中能夠經過迭代 SDK 的方式同步進行,避免中斷。架構
爲了兼容 Uber 移動端響應式編程架構,在設計 Beacon SDK 時,必須暴露可觀察對象(Observable)。使用這個 SDK 的工程師能夠直接經過觀察反應的方式與指示燈進行交互。使用這個 SDK 的工程師能夠直接經過觀察反應的方式與指示燈進行交互。藍牙 API 的使用複雜性被抽象掉了。app
咱們設計的 Beacon SDK 具備一系列的管理器對象(Manager),其中每一個管理器負責指示燈功能的一部分,例如鏈接、LED 控制、無線下載(OTA)更新和傳感器。每組管理器負責與指示燈設備的某個功能互通,司機端 APP 控制這些的管理器來操做指示燈設備。框架
圖 1:Beacon 被分解成多個邏輯管理器,管理器用來反映 Beacon 狀態並提供特定功能。
管理器(Manager)定義了接口,SDK 提供了對應接口的實現。這些管理器封裝了藍牙 API 將命令從司機端傳遞到指示燈設備。
因爲 Beacon SDK 並無提供專用的用戶界面,所以幾乎全部的 Beacon 功能都是經過 worker 提供的。Worker 是本質上是沒有專用UI組件的交互者,所以邏輯與 APP 中的視圖無關。在須要使用指定功能時,Carbon 將 worker 添加到 RIB 樹中實現,當從 RIB 樹中移除時,worker 被分離且被垃圾回收。
每一個 worker 都依賴於一個或多個 Beacon SDK 管理器(Manager)。 管理器被添加給 RIB 裏面的 Worker 對象。當一個 worker 被實例化時,worker 會添加由上游範圍提供的管理器對象。經過這種方式,Beacon 的管理器能夠在全部 worker 之間共享,而且 worker 不負責這些管理器的生命週期。
圖 2:在 Carbon 的 RIB 樹的這一小節中,Beacon 的 Workers 都在 Active 和 Online 的時候纔會生效。管理器在 Active 時被添加依賴並提供給下游 Workers。
RIB 樹讓咱們根據 worker 是否使用 Beacon 功能來決定是啓用仍是禁用插件點(plugin points)。若是禁用 Beacon,插件點則禁用;若是 worker 不被建立,那麼就不會初始化 Beacon SDK 的管理器,從根本上消除了 Beacon 運行時的內存空間。
若是啓用 Beacon 功能,咱們須要遵循協議,worker 纔會被添加到 RIB 樹中。例如 Beacon Alert 管理器,它是在應用內提供例如「低電量」或「指示燈未找到」這種提示窗的管理器。想象一下當司機在家的時候打開 APP 查看他們的收入,此時司機的狀態是離線狀態,由於司機並無開始接單;此時司機並無使用指示燈的需求,所以不須要收到相似的彈窗。咱們只會在司機在路上接乘客的時候(在線時)纔會接入 Beacon Alert 管理器,由於這個時候提示功能纔有意義。
有了 Beacon 框架,咱們能夠在司機端 APP 中實現顏色匹配功能。
如下流程都必須嚴格依賴司機端已鏈接到指示燈設備且此時是在線狀態。當司機在線時,Beacon 的功能 worker 會添加到 RIB 樹上,才能使用司機端的 Beacon 功能更新服務器。隨着司機端的在線與離線,咱們會相應的更新狀態。當司機端斷線時,後端會自動關閉該功能。
當司機端接到乘客的訂單後,乘客端的 APP 就會收到司機的名字、車輛信息以及他們是否具備指示燈的能力。若是具備指示燈功能,咱們會在乘客端 APP 中展現指示燈的圖標。乘客端 APP 會自動給服務器發送以前選擇過的顏色(如乘客從未選擇顏色,則隨機選擇一種顏色),而後通知給司機端 APP 所選顏色。
在等待接駕時,乘客能夠經過點擊指示燈圖標進入顏色選擇頁面(某些特定顏色由於安全合規被移除,例如紅色、藍色),在這裏乘客能夠選擇任何他們中意的顏色。每當乘客選中了一個顏色,就會把這個色值傳遞給後端,後端又通知給司機端 APP。
圖 3:當司機端與指示燈鏈接成功後,就會被通知給後端,當乘客匹配到這個車輛,乘客就能夠選擇一種指示燈顏色。
在司機端這邊,當司機在線時,有個 Beacon Color Worker 一直在監聽顏色變化的通知。當收到了一個新顏色,就會本地存儲一份。這樣,若是司機接受了多個調度,例如拼車場景,咱們會記錄每一個被接駕的乘客所設置的顏色。
圖 4:行程中有不少個拼車乘客,咱們會存儲這些乘客每一個選擇的顏色。
當後端通知咱們已經在去接某個乘客路上時,咱們會給 Beacon 控制顏色的管理器發送一條指令(-經過技術手段得到所匹配乘客選擇的色值),告訴他顯示這個乘客所選中的顏色。同時在接駕過程當中,車輛會不斷更新顯示乘客以後更改的任何顏色,保持乘客端跟司機端的同步。
圖 5:當乘客被接駕時,咱們會檢索他們所選擇的最後一種顏色。
優步一直在尋找優化用戶體驗的方法。軟硬件結合的方式將平臺能力擴展到現實世界是一種天然的進步。軟硬件結合的方式將平臺能力擴展到現實世界帶來了新的使人興奮的挑戰,優步指示燈只是如何在這個領域進行創新的一個例子。這也是優步的移動工程師最激動人心的時刻。