2018 年 11 月 25 日,由又拍雲主辦的 Open Talk | 2018 小程式開發者沙龍杭州站圓滿結束,二維火前端開發工程師糕頭在活動上作了《二維火小程式初探》的分享。
“2018 小程式開發者沙龍”是又拍雲 Open Talk 繼“2018 音視訊技術沙龍”後推出的重磅活動,與大部分偏重營銷、流量的小程式活動不同,又拍雲 Open Talk 主辦的 2018 小程式開發者沙龍更熱衷於分享小程式開發過程的種種有趣經歷和有益經驗。
糕頭,二維火前端開發工程師,主要負責二維火平臺小程式、商家小程式等專案的開發、維護及拓新工作, 支付寶小程式專案負責人,本次主要分享了二維火對 WebSocket 的架構升級、授權流程的優化,以及第三方開發小程式的流程。
以下是分享全文:
小程式與 H5 的對比
小程式的優勢是使用者的成本非常低,即點即用,因為它已經整合在了微信的平臺上,而且可以呼叫更多的手機硬體,例如錄音、GPS 等;而 H5 開發的優點是開發速度快、成本低。那麼如何把 H5 的優點整合到小程式上呢?這就要講一下小程式的一個元件“內嵌”。二維火採用的是混合開發的模式,不僅解決了專案過大的問題,並且能夠快速上線,同時也解決了工程維護的痛點。但是這樣做要在小程式所屬的微信公眾平臺上配置一系列的域名白名單,並且需要犧牲部分的業務,比如廣告等,因此二維火也在逐步轉向原生頁面。
使用 WebSocket 解決頁面實時更新的問題
二維火旗下基於微信小程式專為餐飲客戶開發的應用程式,使用者可通過小程式二維碼進行掃碼點餐、點外賣、排隊、分享、檢視訂單等流程,因此原生頁面需要解決購物車等頁面的實時更新狀態的問題,早期二維火使用輪詢來實現業務,但是更新情況卻不是實時的,總會有一定的時間間隔,所以使用了微信的 WebSocket ,但是微信對 WebSocket 有數量限制,從 2017 年的 1 個到現在的 2 個,雖然有增加,但是還不足以滿足我們的需求。
首先介紹在老版本的 WebSocket 機制上,二維火所走過的坑。
在老的流程上,每進入一個新的頁面就要開啟一個例項,然後再進入新的例項又要斷開老的,每個頁面都要反覆操作這種行為。雖然業務的功能都實現了,但是這種情況下就會有痛點形成,它會極大增加鏈路次數以及導致資訊丟失,因此需要解決這個問題。
在新版本的流程中,全域性只通過持續連線一個 WebSocket 例項,並能實現所有業務,此外引入了“房間”的概念,從開啟新例項到斷開例項,改為“進入新房間”和“離開房間”,目的是保持鏈路數只有一條,對此我們進行了架構的升級。
二維火在原來的 WebSocket 架構升級,通過引入“房間”,以“房間”切割訊息推送範圍。前面提到在老的流程中會增加 WebSocket 的連結數,解決這個問題我們需要當前連結的地址是不變的,這樣使得服務端根本無法區分,如何解決呢?我們通過傳送事件,並攜帶上“房間”的型別和房間引數,比如購物車和訂單頁這兩個房間型別決定了是在哪一個專案頁面,門店的 ID 和座位號這兩個房間引數決定了是在哪家店的哪一個座位,這樣就能夠讓服務端區分出唯一性。簡單來說,“房間”的作用是為了讓服務端能夠區分出每個人的不同。
賦予客戶端訂閱訊息的能力和限定服務端推送只能推送客戶端訂閱的訊息,當連線上 WebSocket 的服務端,並不會馬上推送訊息給 C 端,只有我們傳送了訂閱訊息給服務端,服務端接收到訂閱訊息後,才會往 C 端傳送資訊,並且傳送的資訊只能是 C 端訂閱的訊息,從而杜絕了盲目推送和限定了推送的內容。
增加了異常處理的約定,對異常處理的約定和有 token 的失效,服務端拒絕連結等,因為業務的不同,有不同的約定內容,在這裡就不一一細說。
在技術底層上,二維火為了相容 H5 和小程式,分別用了兩個不同的架構。H5 用的是 http://socket.io,小程式用的是 socket.io-mp-client。
通過上述的概念,我們完成了以上的時序圖。在小程式的全域性入口,建立連線,並且帶上每個使用者的唯一 token 進行辨別是否有效。在 token 有效的前提下,連線建立成功後,由客戶端傳送 join_room 事件,並且帶上房間型別和房間引數。服務端監聽這個事件,並且生成唯一且確定的房間 ID,加入對應的房間。然後通過和後端約定的協議格式,向服務端傳送 subscribe_message 事件,並且帶上需要訂閱的事件名,然後對該事件名進行監聽,之後服務端進行接收並且進行察看,如果有客戶端滿足要求,那麼便對所有滿足要求的客戶端進行推送訊息。
在離開一個頁面的時候,就向服務端傳送 unsubscribe_message 事件,並且帶上訂閱事件名,然後離開事件,那麼服務端將不再推送該訂閱事件。如果關掉小程式,並進行所有連結斷開,服務端判斷我們離開了所有房間,取消了所有的訂閱事件,這樣就能夠實現服務端的精準配送,減少了有效訊息的丟失以及不必要的訊息的推送。
總結一下優化思路,第一,始終保持全域性只有一個連線的 WebSocket ;第二,掌握主動權,需要服務端才能推送,而不是一連線服務端就完全推送。
隱式授權,提高使用者體驗
講到了推送訊息,必然需要用到使用者的個人資訊。那麼如何拿到使用者的個人資訊呢?這裡就需要使用者授權。但是一直讓使用者點選授權是十分影響使用者體驗的,需要做到隱式授權。
隱式授權是儘可能讓使用者無感知授權,甚至做到無需授權,那麼怎麼做到這點?我們先來了解一下為什麼授權。所謂授權,就是需要以下幾個資訊:使用者的個人資訊、使用者的openid、使用者的 unionid。
我們可以利用微信的 wx.login 介面實現小程式的靜默授權。首先它是靜默的且易獲得 openid,在滿足一定條件的情況下甚至能返回 unionid,比如使用者關注過公眾號等。因此,我們假設如果在拿到使用者資訊之後,能夠快取 unionid 和使用者資訊,只要取得 unionid 就可以拿到使用者資訊。如果在使用者授權以後再快取 openid 和 unionid 的對映關係,那麼之後我們只需要呼叫微信 login 介面,拿到 openid 就可以拿到使用者的資訊。簡單的流程就是通過 openid 去獲得 unionid 的對映關係,然後再獲得使用者的資訊。
上圖是最開始也是最簡單的一條流程,新使用者在進入小程式時,會呼叫微信的 login 介面,獲取加密串給服務端,判斷是否能夠拿到 unionid。如果沒有拿到,再去判斷 openid 是否和 unionid 有對映關係。如果在這一步的操作都沒有對映關係,那麼就需要使用者點選授權,這樣是必定能夠返回 unionid 和使用者資訊,然後服務端就會進行快取,使用者在下次進來的時候,只需要通過 openid 去獲取 unionid 的對映關係,就可以拿到使用者資訊,不需要再進行一次次的授權,影響使用者體驗。但是,這個流程必定是需要呼叫微信 login 介面,而萬一出現微信介面掛了,可能會導致業務流程走不下去,所以二維火在這個基礎上進行了優化。
在優化後的流程中,我們加入了一個 token,通過判斷快取中的 token 是否有效,來減少請求微信授權的次數。首先察看快取中是否有 token,並且 token 是否有效。如果有效,服務端便會告訴我們這是否是遊客,如果不是遊客,那麼登陸流程便會結束,也是最快最優的流程。如果此賬戶是遊客,或者 token 是失效的情況下,才會呼叫微信的 login 介面去獲取加密串,然後服務端再返回給我們資訊。這就是我們優化的流程,通過加入自身的驗證 token 來躲過請求微信 login 介面,這樣一套完整的授權流程便能夠走完,能夠使使用者登陸的體驗更加友好,除了第一次需要使用者點選授權之外,之後使用者就不需要再點選授權。
提供平臺服務能力,讓商家擁有自己的小程式
因為很多商家想要自己的小程式 Logo,同時為了解決開放平臺繫結公眾號的數量有限的痛點,所以二維火需要幫助商家開通開放平臺。二維火以第三方服務平臺的身份主要為商家做了以下四個功能:一是幫商家建立開放平臺,二是打通使用者關係,三是優惠券放入微信卡包的生態之中,四是幫商家代註冊小程式。具體來看一下實現的思路。
上圖是商家微信開放平臺的結構支援包,包含了多個商家公眾號、多個商家小程式,一個開放平臺繫結的公眾帳號是有限定的,所以不可能無限制地將商家的公眾號繫結到二維火的開放平臺中,這時候就需要幫助商家擁有自己的開放平臺,快速建立自己的使用者體系。如此,商家能夠更好更有針對性地維護使用者。
上圖是微信開放平臺的文件,通過微信給我們開放的介面獲取預售碼,然後引導商家通過公眾號授權給二維火,通過微信提供 API,幫助商家開通開放平臺,並且繫結商家的公眾號。
在幫商家開通了開放平臺以後,就需要幫助商家打通商家小程式,也就是屬於他們自己的小程式,流程也如上圖,簡單來說,只有三步,首先獲取授權碼,然後呼叫微信開放介面進行快速註冊小程式,第三步是補充小程式的基本知識,把小程式繫結到商家的開放平臺。
二維火的掌櫃端即二維火手機應用 App 讓商家填寫小程式一些基本資訊的介面,需要用到小程式的名稱、頭像、簡潔描述以及資質等。
接下來就是通過微信提供的API,帶上我們之前獲得的小程式的 APP ID 以及待註冊的開放平臺的 APP ID ,就可以把小程式繫結到我們幫商家申請的開放平臺上。同樣,我們可以通過微信提供的 API 進行版本管理,具體可以參照微信開放平臺的文件,這樣商家小程式的體系就基本完成了。具體就是先幫商家建立開放平臺,然後通過它的公眾號繫結在它的開放平臺上,再幫助商家建立小程式,再將小程式繫結到開放平臺上,這樣體系就能夠完成。
如何幫助商家的使用者和二維火的使用者進行打通呢?這裡就要提到平臺和商家的二次授權,使用者在進入二維火系統的時候,會優先判斷是否授權平臺公眾帳號,然後再查詢當前店鋪或者當前業務場景下是否有繫結商家公眾號。如果有繫結,再判斷當前使用者是否需要授權商家公眾帳號,然後對上面兩次授權的資訊進行二次關聯,這樣便完成了業務中的平臺和商家的二次授權。完成了商家的二次授權以後,通過 unionid 的對映關係,可以幫助商家打通平臺使用者和商家公眾帳號粉絲的使用者。後臺進行平臺使用者管理的同時,可以實現更多的營銷功能,如精準配送、定向推送、卡券的功能等,這樣商家不僅可以推送到自己的商家使用者,還可以推到平臺使用者上。
下面介紹微信卡券的功能,如何打通商家卡券與微信卡券的互通?從二維火平臺同步到微信卡包,和微信卡包回到二維火平臺的實踐,需要注意的是,要在開放平臺繫結公眾號 APP ID 和小程式 ID 才能夠實現,然後通過微信開放的介面建立卡券和新增卡券這兩個功能進行實現。
上圖是實現微信卡券功能的兩個關鍵API,具體內容可以參考官方文件,文件對這塊的使用說明已經十分清楚了。
推薦閱讀: