在這以前雖然看過一些博客介紹 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 remote
。java
咱們常見的智能零售或者說其餘的智能硬件的交互屏,通常是一個相似 樹莓派 的板子,而後裝載系統。能夠是 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 初始化會後,頁面都是按照以下處理業務
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 纔會刷新,這個斷開操做可能會干擾到用戶操做。
對於 app 來講有一個用戶重啓 app 的概念,咱們也能夠加一個這個功能,機器會斷電,斷電後能夠更新或者線下運維人員能夠在運維的時候重啓一下。
還有一種方案就是服務向最近10分鐘無狀態的機器推送消息,機器收到消息後強制刷新頁面。
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 標籤是走的 http 協議頭來傳遞,直接設置 http 協議頭不是也能夠解決問題嗎
強緩存
協商緩存
詳細學習能夠參考資料HTTP 緩存機制一二三
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天或者半天就能完成的工做,剩下的時間讓你加班你是否是能夠繼續折騰了?但這些都須要創建在基礎服務完善的基礎之上,沒事的時候就完善通用組件,工具函數,基礎樣式類等,相應的服務端也須要配合演進,不斷打磨中才能更好的完善穩定。
上去就是幹!