您當前位置>首頁 » 新聞資訊 » 小(xiǎo)程序相(xiàng)關 >
基于一(yī)個(gè)好(hǎo)玩(wán)兒(ér)的(de)>✔聊天室理(lǐ)解小(xiǎo)程序 session 管理(lǐ)
發表時(shí)間(jiān):2021-3-31
發布人(rén):葵宇科(kē)技(jì)
浏覽次數(shù):107
panda-chat-room
小(xiǎo)程序版 websocket 聊天室。 從(cóng)服務器(qì)到(dà×≈εo)小(xiǎo)程序客戶端配置基礎教程。
在本教程內(nèi)我們将在小(xiǎo)程序內(nèi)實現(xiàn)一(yī)個(gè)基φΩ↓本的(de) websocket 聊天室, 計(jì)劃實現(xiàn)以下(xià)功能(nén♥"g):
- 微(wēi)信用(yòng)戶登錄「 小(xiǎo)程序 session 管理(lǐ)Ω↓ ≤ 」:ballot_box_with_check:
- 用(yòng)戶間(jiān)文(wén)本交流 「 websocket 實現λ∏(xiàn) 」:ballot_box_with_check:
- 用(yòng)戶間(jiān)發送圖片等富媒體(tǐ)信息 「 文(wén)件(jià₩£n)的(de)儲存及相(xiàng)關邏輯 」:ballot_box_with_check¥&←:
小(xiǎo)程序已挂,原因是(shì)個(gè)人(rén)開(kāi)發者無法提交信息交流類小γ (xiǎo)程序, 不(bù)過在本地(dì)運行(xíng) "'σdemo 還(hái)是(shì)沒問(wèn)題的(de)。
寫的(de)有(yǒu)纰漏的(de)地(dì)方還(háπαi)請(qǐng)大(dà)家(jiā)指出,在 SF 下(xià)留言或在&π♣↕₹nbsp;本項目 git 內(nèi)提 issue ,我≥≈們一(yī)起進步 ^o^
聊天室基礎配置
小(xiǎo)程序端的(de)聊天室信息流其實非常簡單, 而本教程就(jiù)借助一×α™(yī)個(gè)好(hǎo)玩(wán)兒(ér)的(d✔'e)小(xiǎo)程序聊天室來(lái)進一(yī)步理(lǐ)解小(xi±ǎo)程序中的(de) session 實現(xiàn)。
我在服務器(qì)端環境搭建及配置主要(yào)參考騰訊雲實驗 基于 Cen'✘ tOS 搭建微(wēi)信小(xiǎo)程序服務
我們在此先要(yào)理(lǐ)解小(xiǎo)程序端為(wèi)何無法實現( ∏∞xiàn) session, 以及如(rú)何在小(x"↑∑ iǎo)程序實現(xiàn) websocket 通(tōng)信。
小(xiǎo)程序并非嵌套在微(wēi)信內(nèi)的(de) html5 網頁, 它↕α↑®并不(bù)是(shì)從(cóng) url 訪問(wèn)到(dào)的(de)。α☆ 我們隻能(néng)自(zì)己實現(xiàn)類似會(huì)話(huà)的(↔₹de)東(dōng)西(xī), 好(hǎo)在官方已經提供了(le)相(xiàng↓Ω♠↑)應的(de)套件(jiàn)來(lái)實現(xiàn) sesγ©sion。 即 wafer-client-sd¶' k 和(hé) node 中間(jiān)件(jià ≥↓n) wafer-node-session >Ω, 我們依照(zhào)文(wén)檔就(jiù)能(néng)簡單地(dì)實現(xiàn) ↕session。
騰訊雲 wafer 項目下(xià)有(yǒu)很(hěn)多(duō)相(xiàng)★•似項目「大(dà)部分(fēn)需要(yào)配合騰訊雲進行(xín₩λ↑∑g)一(yī)鍵部署」, 如(rú)果我們隻需要(yào)實現(xiàn ∏←ε)小(xiǎo)程序 session 管理(lǐ)的(de)話(huà), wafer-π÷↕client-sdk 和(hé) node 中間§β₽★(jiān)件(jiàn) wafer-node-session&nb♦×®₹sp;即可(kě)。
在服務器(qì)端我們使用(yòng)了(le) ws 包♥♦β 來(lái)實現(xiàn) websocket ,沒有(yǒu)使用(yòng) sockΩ↔'et.io 的(de)原因是(shì) socket.io 需要(yào)客戶端有(yǒu)額外×±(wài)的(de)腳本才能(néng)實現(xiàn∞₹ ♠)通(tōng)信。
在小(xiǎo)程序端我們引入 wafer-client×♠"π-sdk 套件(jiàn)使服務器(qì)可(kě)以獲取 session。
主要(yào)邏輯分(fēn)為(wèi)幾個(gè)簡單函數(shù), 當然你¥€(nǐ)需要(yào)先配置請(qǐng)求的(de)服務↑π♥器(qì)域名和(hé)小(xiǎo)程序賬号密碼。
// 引入 session 套件(jiàn), 裡(lǐ)面封裝了(le) w •x.login, wx.getUserInfo 等操作₹÷¶★(zuò)
const wafer = require('../../vendors/wafer-client-s↔dk/index')
// 用(yòng)于登錄使服務器(qì)獲得(de) session, 然後服務器(q>↓ì)返回的(de) session 裡(lǐ)就(jiù)會(γ→✘huì)包含用(yòng)戶信息了(le), 用(yòng)來(lái)在 websocket 裡<→σ(lǐ)返回發信息用(yòng)戶的(de)頭像 url
function login(){
.....
}
// 用(yòng)于有(yǒu)新信息時(shí)更新數(shù)據, msg ←↑✘指信息, ad 指 websocket 傳回的(de)信息 id, 用(yòng)→•于 scroll-into-view 滾動
pushMsg(msg, ad) {
.....
}
// 用(yòng)于監聽(tīng) websocket 連接
listen(){
.....
}
// 用(yòng)于小(xiǎo)程序發送 websocket 信息
send(){
.....
}
基本就(jiù)是(shì)這(zhè)些(xiē), 關于÷£↑ websocket 通(tōng)信過程是(shì)這(zhè)樣的(de):
- 客戶端發送信息給服務器(qì) m1
- 服務器(qì)收到(dào)信息後根據條件(jiàn)返回給客戶端 m2
- 每個(gè)客戶端收到(dào) m2 後更新視(shì)圖
當然最開(kāi)始是(shì)要(yào)與服務器(qì)端 webso∞∞✔ cket 連接的(de), 隻有(yǒu)每個(gè)連接了(le)的(de)客ε∞$戶端才可(kě)以交流信息。
小(xiǎo)程序 session 解析
對(duì)于 session 的(de)實現(xiàn)我們在服務器(qì)端使用(yòngσ↔←÷)了(le) wafer-node-session ™≈即為(wèi)連接提供 session 能(néng)力。 在小(xiǎo≈"™)程序端我們配套使用(yòng)了(le) wafer↕♣-client-sdk , 這(zhè)裡(lǐ)面封裝了(le) wx.r≤±±equest、 wx.login 等邏輯, 實現(xi♠ε•àn)了(le)小(xiǎo)程序端的(de)用(yòng)戶登錄、session 設置。$ γ
關于小(xiǎo)程序端的(de) session 獲取問(wèn)題主要(yà∞♣₹o)有(yǒu)如(rú)下(xià)幾個(gè)步驟
- wx.login 獲取 code
- wx.request 發送 code 給自(zì)己的(de)服務器(qì) "
- 服務器(qì)收到(dào) code 配合 appId 和(hé) ÷§appSecret 發送給微(wēi)信服務器(qì)換取 openId 和¥₹σ₩(hé) sessionKey
- wx.getUserInfo 會(huì)得(de)到(dào) ra>≤↔wData、signature、encryptedData、 iv, 我們需要(yào)把它♦¶們發送到(dào)自(zì)己服務器(qì)。 我們構建÷≠β自(zì)己的(de) signature2 = sha1(ses©sionKey + rawData) , 比對(duì) s₹φignature 和(hé) signature2 就(ji$<↑ù)完成了(le)數(shù)據校(xiào)驗
- 服務端通(tōng)過 aes-128-cbc 算(suàn)法對(duì)稱解密 enc ¶€ryptedData 和(hé) iv 然後得(de)到(dào) δ↕userInfo 這(zhè)次得(de)到(dào✘')的(de) userInfo 裡(lǐ)還(hái)包含 openId 等信息♦± ∑ 「如(rú)果在微(wēi)信開(kāi)放(fàng)平γ 台綁定小(xiǎo)程序就(jiù)會(huì)得(de)到λ✔(dào) unionId」
- 服務端構建 req.session 對(duì)象并返回給小(xiǎ&£ o)程序,裡(lǐ)面包含 id、 userInfo、 sessionKey「小(xiǎo) ∞程序傳到(dào)服務器(qì)的(de)」、skey 「服務器(qì)自(zì)己根據sess✘≥₩™ionKey + appId + appSecret 生(shēng)成, 有(yǒu)過期時(sε∞™hí)間(jiān)」。 而我們自(zì)己生(shēng)成的(''λde) skey 是(shì)有(yǒu)設置過期時(shí)間(jiān)的(de)♥©, 但(dàn)小(xiǎo)程序端的(de) sessi÷∞₩on 也(yě)有(yǒu)自(zì)己的(de)過期時(shí)間(jiān) 「應該是(✔αshì)微(wēi)信按使用(yòng)小(xiǎo)程序的(de)頻(pín)率來(l₽ε✘ái)動态設置過期時(shí)間(jiān)的(de)。 wafer 會(huì∞€)自(zì)動調用(yòng) wx.checkSess≥<ion 檢查是(shì)否過期, 過期了(le)就(jiù) wx> ☆.login」。
在我們的(de) demo 中就(jiù)出現(xiàn)了(le)服↓™務器(qì) session 已經過期而本地(dì) session ≤€§還(hái)沒過期的(de)情況。 而 websocket 每次發送信息都(™εdōu)需要(yào)從(cóng) req.session 內(nèi)獲取用(yòng)戶頭像α∞απ, 所以會(huì)導緻 websocket 連接失敗。 但(dàn)是( Ω✔shì)在小(xiǎo)程序端 session 未過期,即在服務器(qì)端的(de) ses≥§♣sionKey 和(hé)小(xiǎo)程序的(de) sessio©∏nKey 不(bù)一(yī)緻了(le) 「客戶端 sess™↑ionKey 還(hái)在而服務器(qì)的(de) sessionKe'♥₽πy 已經過期銷毀」, 導緻比對(duì)失敗。 那(nà)怎麽辦呢(ne)? 重新請(qǐng)求δ>呗! 但(dàn)是(shì)因為(wèi) wafer 封裝了(le) s≈≤™λession 管理(lǐ) 「小(xiǎo)程序端 session 過期後才會(huì)重新請(π₽ qǐng)求」 存在 session 緩存的(de)緣故, 小(xiǎo)程序并沒有(y£₹λ✘ǒu)重新發送信息給自(zì)己的(de)服務器(q≠γ↔ì)進而生(shēng)成新的(de) sessionKey, 所以我們在每一( ♣₽≤yī)次 wx.sendSocketMessage 發信息的(de)時(shí)候都(d✘Ωōu)要(yào)檢查服務器(qì)端的(de) session 情況, 這(zhè)裡(l←"Ωǐ)需要(yào)做(zuò)簡單的(de)判斷「webπ£✔$socket 信息有(yǒu)錯(cuò)誤就(jiù)清除本地(dì) sessiβ♥αon」讓小(xiǎo)程序重新請(qǐng)求服務器(qì)。
websocket 信息發送
既然要(yào)發送信息「即産生(shēng)數(shù)據」, 那(nà)麽這(zhè)些(≥✔xiē)信息都(dōu)儲存在哪裡(lǐ)呢(ne)? 在發送文($¶£wén)本信息時(shí), 服務器(qì)端收到(dào)數(shù)γ≥£據後隻做(zuò)簡單地(dì)處理(lǐ)便返回給小(xiǎo)程序, 這(zhè)時(shε$☆í)的(de)數(shù)據應該是(shì)儲存在服務器(qì)內(nèi)存中。 因為β™(wèi) websocket 在收到(dào)請(qǐng)求後簡單處理(lǐ)了(le)✘≠≠字符串信息直接返回給小(xiǎo)程序, 那(nà)我們發送其它富媒體(tǐ)信息時(shí),也☆™§★(yě)可(kě)以以二進制(zhì)的(de)方式發送給 web γδsocket 服務器(qì), 然後重新返回給客戶端 「即 weπ×♠bsocket 隻做(zuò)文(wén)件(jiàn)中轉」,相(xiàng"π)關實現(xiàn) websocket-stream 。α™♣ 貌似看(kàn)起來(lái)很(hěn)複雜(zá),在這(zhè)裡(lǐ)我使用(±≈yòng)了(le)國(guó)內(nèi)的(de) paas 服務商σ leanCloud 的(de)儲存服務 「即小(xiǎo)程×∏↑序端把發送的(de)文(wén)件(jiàn)儲存在 >∑雲端,返回一(yī)個(gè)文(wén)件(jiàn)地(dì)址」,然後我們把 ∑這(zhè)個(gè)文(wén)件(jiàn)信息進行(xíng)标注「即隻發送文(wé±↕₩εn)件(jiàn)的(de) url 信息, 小(xiǎo)程序端判斷請(qǐng<♠≤)求是(shì)否是(shì)文(wén)件(jiàn)進而顯示」。 當 €•♥然你(nǐ)也(yě)可(kě)以發送視(shì)頻(pín)或者音(yīn)頻×φ♥∞(pín), 把他(tā)們都(dōu)保存在雲端,₹✘α 隻發送其相(xiàng)應的(de) url 即可(γ≥kě)。 我們這(zhè)裡(lǐ)的(de) websocket 服務器(qì)隻做(zuò)αβ↔§一(yī)個(gè)文(wén)件(jiàn)中轉的(de)功能(néng), 而文(wφ<∑↕én)件(jiàn)的(de)存儲交給雲端來(lái)負責。
panda-chat-room 項目源碼
項目源碼 :https://github.com/hiscc/ ÷♦←panda-chat-room