公司的一款即時通信web產品,以前設計的架構是聊天消息按期從IM服務器獲取,這會致使若是用戶刷新頁面,會丟失最近的聊天對話消息。因爲以前定時間隔在分鐘級別,因此問題不是很明顯。最近因爲種種緣由,消息同步間隔變長到小時級別,從而將消息丟失的問題凸顯出來,工單不斷。web
設計思路
採用localstorage實現web端本地消息緩存是此次設計的主體思路。由於產品對低版本瀏覽器默認不支持,所以也就不須要考慮瀏覽器的兼容性問題。關於localstorage的介紹請參見(developer.mozilla.org/zh-CN/docs/…);數組
- 進入頁面,檢查一下本地緩存的粉絲消息是否過時,若是過時,則清除。以粉絲爲單位;
- 點擊某個粉絲,從服務器獲取20條歷史消息。獲取該粉絲本地緩存消息,二者以最新時間對比,若是服務器是最新的,就清除該粉絲本地緩存,而且同步本地緩存。若是本地最新,則採用本地緩存。其考慮的主要目的是考慮到當前離下一次服務器同步很近,且用戶又在其餘電腦上與該粉絲聊過的場景,保證最快更新到本地緩存;
- 主動發送和接收到的聊天消息,push到該粉絲對應的本地隊列。(檢查消息條數封裝在內部實現);
- 客服關閉該粉絲,或刷新了本頁面。當再次切換到該粉絲時,重複步驟 1 ;
評估:
locastorage的最大配額各瀏覽器基本是5MB。如下的計算都是估算,大體認爲1KB=1000byte,1MB=1000KB。實際是以1024 換算。這裏只估算。
若是須要緩存50個粉絲,那麼每一個粉絲分配的空間:5MB/50=0.1MB=100KB;
假設一個消息100字節(1個英文字符佔1個字節,漢字屬於雙字節,佔兩個字節)。那麼每一個粉絲能夠緩存消息數:100KB/100byte=100 * 1000/100=1000 條 瀏覽器
定義配置參數:
- fansLimit:50;緩存的粉絲個數
- msgLimit:100;緩存的粉絲消息條數;
- expired:1000 60 60 * 2;緩存有效時間,單位:ms;
緩存格式:
- 在localStorage上定義個緩存變量:msgCache。裏面存儲的每一個字段對應一個粉絲的緩存;
- 以粉絲的id爲key,{{fansid}},值爲對象。例如:{time:122222222,msgs:[{msg}]}
- fansid:粉絲的id;
- time:最新的活躍時間。每次添加緩存的時候同步更新.存毫秒值格式;
- msgs:緩存粉絲的具體業務數據數組,每一項表明一條消息,消息的格式參見業務消息object便可。
檢查內容:
- 粉絲消息過時檢查(A),檢查粉絲的最新活動時間是否超過設置的過時時長,超過則remove該粉絲緩存;
- 粉絲消息條數檢查(B),檢查改粉絲條數若是超過限制,刪除最先的消息,直接用隊列,先進先出;
- 刪除粉絲緩存(C);直接刪除粉絲緩存
緩存檢測時機:
- 頁面加載時遍歷粉絲緩存,執行A;
- 讀取localstorage的時候,執行A;
- 設置粉絲消息緩存的時候,執行B;(這裏能夠不用執行A)
- 設置緩存出現異常(quotaExceedError,表示超過localstorage最大限制),執行C;
總結
- 關於緩存超出最大配額的處理比較粗糙,能夠考慮設計一種動態擴容的方案;
- 若是用戶在聊天過程當中更換了電腦,瀏覽器產品,仍是會有消息丟失的狀況;
- 最根本的解決方案,仍是由服務端實時保存聊天消息記錄。