結識hybrid體驗這一年

在這以前雖然看過一些博客介紹 hybrid,可是始終沒有具體應用場景,想象的就是我如今作好了一個網站,而後 native 直接在 webview 中打開個人網站,相似瀏覽器中打開網站同樣,頭部添加一個相似瀏覽器的返回按鈕,若是隻是考慮到安卓或許這一步都不必。javascript

認真接觸 hybrid 是在入職後的第一個項目,項目是基於 Hybrid/webapp at gh-pages · yexiaochai/Hybrid · GitHub 其中視圖部分在原項目基礎上引入了 vue ,目錄結構等都是和以前項目一致,頁面和組件能夠直接使用 vue 語法,hybrid 協議有些許變化。vue

沒有 webpack 項目的啓動依賴 Charles map local 預覽項目,mock 工具當時使用的是 easy-mock 中間跨域的解決方案是 Charles map remotejava

硬件交互

咱們常見的智能零售或者說其餘的智能硬件的交互屏,通常是一個相似 樹莓派 的板子,而後裝載系統。能夠是 win,android,也能夠是 ios。開發須要 native 初始化一個 webview,而後定義一些通用協議,加載一個頁面彷佛就完活了。react

通信協議

開發過程當中咱們須要 native 賦予咱們一些能力,咱們須要約定一下通信協議的格式,其中參數 tagname:協議名稱;param:協議參數;callback:協議回掉(native處理成功之後可能須要返回一些參數信息) 。 格式以下:android

{
	tagname: '', // 
	param: {},
	callback() {}
}
複製代碼

遠程操做

例如用戶掃碼購買了一瓶飲料,我想在零售屏上切換一個歡迎使用的頁面,這個時候須要在 用戶-零售屏 上創建關係,這中間可能須要一個服務端。用戶一開始和服務端創建聯繫,正常的下單購買,購買成功後,服務端推送一條消息給零售機,告訴他有用戶買了瓶飲料,你如今給他推一個飲料出來。webpack

用戶 -> 掃碼 -> 購買 -> 服務 -> 出貨ios

用戶掃描機器上的二維碼,這個行爲會觸發一個與當前售賣機綁定的操做,綁定成功後服務能夠推送一個消息給零售屏,零售屏接收到消息後會切換到歡迎界面,後續的交互包括支付成功,出貨成功這些消息若是要表示到零售屏上都是一樣的道理。用戶與服務,服務與零售屏他們時如何通信的呢?nginx

用戶與服務之間是數據請求,服務與零售之間爲了通信保持,創建的是 websocket 鏈接,零售機內部是 hybrid ,native 調用硬件能力。git

問題分析

開發過程當中碰見過一些問題,應該是 hybrid 應用開發也會遇到這些問題,相對而言這些問題對比一個成熟的 hybrid 方案要解決的問題要輕不少。github

websocket 心跳重連問題

這個問題是消息推送相關。websocket 初始化會後,頁面都是按照以下處理業務

const ws = new WebSocket('url');
	ws.addEventListener('error', e => {
		// 去維護頁面
	})

	ws.addEventListener('message', event => {
		// 按消息內容處理事件邏輯
	})

	ws.addEventListener('open', event => {
		// 定時發送消息 4min NAT
	})

	ws.addEventListener('close', event => {
		// 去維護頁面
  })

	ws.addEventListener('disconnect', event => {
		// 去維護頁面
	})
複製代碼
  • 單頁應用容器內維持狀態,組件內展現業務狀態。遠程操做時提到的服務與零售屏之間的通信是 websocket ,零售屏中經過監聽 message 來調用對應的方法處理相應的邏輯。有指定的故障頁面,故障會跳轉到故障頁面,故障有:機器斷網(native捕捉處理),請求超時,服務端主動更新斷開,運維維護斷開等等狀況,若是是 websocket 斷開會定時刷新頁面從新鏈接,若是是 websocket 沒有斷開,數據請求超時等,定時再次請求,若是請求成功切換頁面。

這裏有另一個問題,零售屏頁面更新的問題,以前是進入維護頁面會定時刷新頁面,這樣若是頁面更新下次刷新確定能夠更新到新的頁面,如今更改爲只有斷開 websocket 纔會刷新,這個斷開操做可能會干擾到用戶操做。 對於 app 來講有一個用戶重啓 app 的概念,咱們也能夠加一個這個功能,機器會斷電,斷電後能夠更新或者線下運維人員能夠在運維的時候重啓一下。 還有一種方案就是服務向最近10分鐘無狀態的機器推送消息,機器收到消息後強制刷新頁面。

  • 定時發送業務心跳消息。在這以前沒有定時去發送消息,會出現一種狀況是受其餘緣由被關閉了,websocket 並不會監聽到關閉或斷開或錯誤,這樣就不會去從新鏈接,這時用戶的操做零售屏是收不到任何消息的。服務推送消息是正常推送會提示已經斷開。 Pings have an opcode of 0x9, and pongs have an opcode of 0xA 心跳的發送都是底層協議來作的,可是會涉及到一個問題就是NAT超時鏈路會被斷開,這個時候若是業務沒有數據傳遞,客戶端不會從新創建鏈接,若是零售屏沒有消息發送就不能出發關閉時間,若是零售機就失聯了,按照Android微信智能心跳方案設置了一個業務心跳,維持長連接的活動,這樣以來不會觸發用戶掃碼無響應機器失聯的狀況。 服務能夠根據掃碼加推送消息日誌來判斷有沒有具體失聯,若是失聯能夠調整業務心跳的觸發時間。

緩存方案

一開始 Native 認爲緩存問題很難處理,直接就在配置中沒有使用緩存,每次頁面加載都會直接從新從線上加載資源(LOAD_CACHE_ONLY),個人每個狀態頁面切換也都會耗費資源流量,首頁加了一個視頻啊,1G的流量卡如何是好?網絡很差的狀況下如何是好? 搜索發現 android 在 webview 中能夠有幾種形式設置緩存

// 緩存模式以下:
// LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據
// LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。
// LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據.
// LOAD_CACHE_ELSE_NETWORK: 只要本地有,不管是否過時,或者no-cache,都使用緩存中的數據。
複製代碼

經過 nginx 配置 http 的緩存協議頭,可使用 LOAD_DEFAULT ,經過緩存協議來控制。頁面的發佈每一次都會根據內容以 hash 的名字命名編譯文件,每次發佈都能保證修改後的文件會從新從走線上資源拉取。

  • meta標籤,瀏覽器在請求文檔資源時會在請求頭上攜帶 content 信息,能夠處理緩存問題,可是對於非瀏覽器緩存的狀況下這種形式就失效了
  • meta 標籤是走的 http 協議頭來傳遞,直接設置 http 協議頭不是也能夠解決問題嗎
    • 強緩存
      • Expires HTTP/1.0 指緩存過時的時間,超過了這個時間點就表明資源過時
      • Cache-Control HTTP/1.1 指定一個時間長度,在這個時間段內緩存是有效的,單位是s
    • 協商緩存
  • 本地資源緩存,可能咱們有時須要更新 app 資源包的形式來更新一些資源,是直接使用 file:// 的形式來讀取資源好一些呢?仍是直接走 http:// 的形式好一些呢?很明顯是後者,若是緩存有,強緩存直接用本地。協商緩存或者緩存沒有 native 有直接攔截請求作響應,若是沒有,直接走線上請求。 編譯項目之後,項目靜態資源能夠按需打包到 app 中隨 app 的更新升級作升級。

圖片資源渲染問題

零售屏的二維碼信息時動態更新的,有一個很詭異的bug是二維碼偶爾會出現緩存的問題。瀏覽器渲染機制以及vue內部運行機制,沒有深刻沒有發言權,後續如何提高這也是一些方向。 爲了解決圖片的緩存的問題,請求的時候咱們都會在圖片的地址上帶上時間戳。詭異的問題描述以下(如下數據都是經過日誌記錄所得):

1. 生成:11:20:34 130281
2. 生成:11:20:50 399538
3. 生成:11:35:09 123391
4. 使用:11:35:15 123391
5. 生成:11:35:30 117602
6. 使用:11:35:37 399538
7. 使用:11:35:44 399538
8. 使用:11:38:29 399538
9. 使用:11:38:42 399538
複製代碼

11:20:50生成一個二維碼,11:35:09生成一個二維碼並正常使用,說明渲染爭取,11:35:30服務日誌記錄最新生成的碼上的信息和用戶上傳上來的信息不一致,若是說請求還沒響應,圖片應該是上一次的正常使用時的狀況,不會出現上上次的二維碼。代碼邏輯時按也許需求去續改src。

<img src="" />
複製代碼

能力有限沒能找到問題所在,解決方案不能沒有啊,刷新時等待圖片加載成功後再插入整個圖片元素。不是單純的更新一個屬性,而是整個元素。

系統字體大小修改影響網頁字體大小

實際零售屏都是一個標準,這個需求是一個相對而言的僞需求,創建在不會有人去修改系統配置的狀況下,若是有要麼 native 控制,要麼頁面用相對尺寸,px 會按照設置的字體受影響。

多小程序掃同一個碼的需求

零售對應用戶,維護對應運營。運營有一些特殊的權限,不想影響到用戶,單獨須要作一個小程序,用戶端和運維端同時去掃描用戶端的小程序,運維端是拿不到任何小程序上的數據信息。 小程序也考慮到了兼容用戶以前的二維碼的狀況,因而有了一個自定義二維碼的規則,按照本身的業務規則配置連接,而後生成二維碼,不管是微信掃一掃,用戶或者運維小程序內部掃一掃均可以拿到二維碼上的業務信息,同時爲了兼容以前的小程序碼的掃碼須要作一個掃碼收口處理。

如何進階

這個是我一直在思考的問題,一年前剛剛入職的時候給的目標是一年對比以前的兩年,如今看來一年不如一年,以前還能儘可能保證按時學習新的知識點,惟一有出入的是如今能夠學而實踐之。從某些方面來講這一年是沒有達到預期的。

沉澱

從入職到如今項目起起伏伏不少次,hybrid 技術方案也有 blade,blade-vue,blade-scripts,react-hybrid,rn(名字我按照本身的實際使用劃分),小程序也有使用原生小程序,wepy,mpvue,也從 javascript 也部分到 typescript ,若是隻是把本身侷限在某一個語言或者某一個框架,這樣始終是瞭解如何使用這個框架,學習從文檔開始均可以上手。 Hybrid 從 blade 演進到如今已是第四個版本了,基本的思想都是在繼續沿用,改進的只是技術方案。這也是我想到在實際工做中不能侷限某種語言或方案,能想辦法把當前工做用的技術方案沉澱下來,延續到之後的工做,不能每一次開局一把刀,裝備全靠撿,積累很重要。

基礎服務

在不斷升級過程當中也暴露了一些問題,中間也說明了基礎服務的重要性,剛開始時是0,計劃的是半年內趨於穩定,後面加班的時候會愈來愈少,後面發現不加班能解決的問題就是換家工做,差異在於加班時你在作的是什麼? 若是是沒有沉澱的狀況下你可能須要2天,沉澱後1天或者半天就能完成的工做,剩下的時間讓你加班你是否是能夠繼續折騰了?但這些都須要創建在基礎服務完善的基礎之上,沒事的時候就完善通用組件,工具函數,基礎樣式類等,相應的服務端也須要配合演進,不斷打磨中才能更好的完善穩定。

上去就是幹!

其餘問題

相關文章
相關標籤/搜索