小程序版 websocket 聊天室。 從服務器到小程序客戶端配置基礎教程。html
在本教程內咱們將在小程序內實現一個基本的 websocket 聊天室, 計劃實現如下功能:html5
小程序已掛,緣由是我的開發者沒法提交信息交流類小程序, 不過在本地運行 demo 仍是沒問題的。node
寫的有紕漏的地方還請你們指出,在 SF 下留言或在 本項目 git 內提 issue ,咱們一塊兒進步 ^o^
小程序端的聊天室信息流其實很是簡單, 而本教程就藉助一個好玩兒的小程序聊天室來進一步理解小程序中的 session 實現。 git
我在服務器端環境搭建及配置主要參考騰訊雲實驗 基於 CentOS 搭建微信小程序服務github
咱們在此先要理解小程序端爲什麼沒法實現 session, 以及如何在小程序實現 websocket 通訊。web
小程序並不是嵌套在微信內的 html5 網頁, 它並非從 url 訪問到的。 咱們只能本身實現相似會話的東西, 好在官方已經提供了相應的套件來實現 session。 即 wafer-client-sdk 和 node 中間件 wafer-node-session, 咱們依照文檔就能簡單地實現 session。算法
騰訊雲 wafer 項目下有不少類似項目「大部分須要配合騰訊雲進行一鍵部署」, 若是咱們只須要實現小程序 session 管理的話, wafer-client-sdk 和 node 中間件 wafer-node-session 便可。
在服務器端咱們使用了 ws 包來實現 websocket ,沒有使用 socket.io 的緣由是 socket.io 須要客戶端有額外的腳本才能實現通訊。npm
在小程序端咱們引入 wafer-client-sdk 套件使服務器能夠獲取 session。小程序
主要邏輯分爲幾個簡單函數, 固然你須要先配置請求的服務器域名和小程序帳號密碼。微信小程序
// 引入 session 套件, 裏面封裝了 wx.login, wx.getUserInfo 等操做 const wafer = require('../../vendors/wafer-client-sdk/index') // 用於登陸使服務器得到 session, 而後服務器返回的 session 裏就會包含用戶信息了, 用來在 websocket 裏返回發信息用戶的頭像 url function login(){ ..... } // 用於有新信息時更新數據, msg 指信息, ad 指 websocket 傳回的信息 id, 用於 scroll-into-view 滾動 pushMsg(msg, ad) { ..... } // 用於監聽 websocket 鏈接 listen(){ ..... } // 用於小程序發送 websocket 信息 send(){ ..... }
基本就是這些, 關於 websocket 通訊過程是這樣的:
固然最開始是要與服務器端 websocket 鏈接的, 只有每一個鏈接了的客戶端才能夠交流信息。
對於 session 的實現咱們在服務器端使用了 wafer-node-session 即爲鏈接提供 session 能力。 在小程序端咱們配套使用了 wafer-client-sdk, 這裏面封裝了 wx.request、 wx.login 等邏輯, 實現了小程序端的用戶登陸、session 設置。
關於小程序端的 session 獲取問題主要有以下幾個步驟
在咱們的 demo 中就出現了服務器 session 已通過期而本地 session 還沒過時的狀況。 而 websocket 每次發送信息都須要從 req.session 內獲取用戶頭像, 因此會致使 websocket 鏈接失敗。 可是在小程序端 session 未過時,即在服務器端的 sessionKey 和小程序的 sessionKey 不一致了 「客戶端 sessionKey 還在而服務器的 sessionKey 已通過期銷燬」, 致使比對失敗。 那怎麼辦呢? 從新請求唄! 可是由於 wafer 封裝了 session 管理 「小程序端 session 過時後纔會從新請求」 存在 session 緩存的緣故, 小程序並無從新發送信息給本身的服務器進而生成新的 sessionKey, 因此咱們在每一次 wx.sendSocketMessage 發信息的時候都要檢查服務器端的 session 狀況, 這裏須要作簡單的判斷「websocket 信息有錯誤就清除本地 session」讓小程序從新請求服務器。
既然要發送信息「即產生數據」, 那麼這些信息都儲存在哪裏呢? 在發送文本信息時, 服務器端收到數據後只作簡單地處理便返回給小程序, 這時的數據應該是儲存在服務器內存中。 由於 websocket 在收到請求後簡單處理了字符串信息直接返回給小程序, 那咱們發送其它富媒體信息時,也能夠以二進制的方式發送給 websocket 服務器, 而後從新返回給客戶端 「即 websocket 只作文件中轉」,相關實現 websocket-stream 。 貌似看起來很複雜,在這裏我使用了國內的 paas 服務商 leanCloud 的儲存服務 「即小程序端把發送的文件儲存在雲端,返回一個文件地址」,而後咱們把這個文件信息進行標註「即只發送文件的 url 信息, 小程序端判斷請求是不是文件進而顯示」。 固然你也能夠發送視頻或者音頻, 把他們都保存在雲端, 只發送其相應的 url 便可。 咱們這裏的 websocket 服務器只作一個文件中轉的功能, 而文件的存儲交給雲端來負責。
項目源碼 ☑️