webman/push版本號: "v1.0.17"
webman/redis-queue版本號: "v1.3.1"
想解決的問題就是通過webman/push插件和redis消息隊列來向訂閱用戶頻道的用戶發(fā)送即時消息時,需要針對用戶來識別哪些消息被讀取了或者是發(fā)送消息前能否感知到用戶是否在線
1、向瀏覽器發(fā)送消息首先將要發(fā)送的消息加入redis隊列,有即時發(fā)送和延遲發(fā)送兩種方式
2、在redis的消費進(jìn)程中觸發(fā)webman/push的動作,框架本身是否存在函數(shù)或者全局變量來感知某用戶是否在線,還是只能通過db去記錄用戶在線狀態(tài),會造成性能和mysql的壓力問題
3、webhook的代碼看了下,一般做為統(tǒng)計,或者檢測用戶上線后去觸發(fā)消息推送,以及一些定制化動作
1、服務(wù)端只負(fù)責(zé)推,不考慮用戶是否在線
2、客戶端在接收到服務(wù)端的消息后,請求一個回調(diào)接口給到服務(wù)端,服務(wù)端根據(jù)接口請求參數(shù)來感知該消息用戶是否已讀,并從消息隊列中移除該用戶的該條消息
3、用戶登錄時,將用戶的全部未讀消息發(fā)送出去
顧慮:
1、這樣的話,每條消息都會觸發(fā)一次接口回調(diào)請求,是否合理
2、服務(wù)端只管推送,浪費的服務(wù)器資源不可控
十分推薦使用Gateway,非常成熟且絲滑。
http://m.wtbis.cn/doc/gateway-worker/is-online.html
http://m.wtbis.cn/doc/gateway-worker/send-to-client.html
http://m.wtbis.cn/doc/gateway-worker/bind-uid.html
??,感謝,目前我是在webman的webhook里封裝了類似gateway的isonlie函數(shù)來處理用戶在線狀態(tài),redis集群的話性能也扛得住
websocket業(yè)務(wù)同時在線低于5萬的用不到gatewayWorker,用webman/push更輕量好用。
建議以下方案:
消息隊列用不到,除非你有什么特殊業(yè)務(wù)。
webhook可以用來做用戶上線離線標(biāo)記,在線離線可以記錄到數(shù)據(jù)庫當(dāng)中。不過根據(jù)上面架構(gòu)不用判斷用戶是否在線,這部分可以不做。
了解
1、我現(xiàn)在是消息記錄到數(shù)據(jù)庫,webhook中redis維護(hù)監(jiān)聽用戶的上下線狀態(tài)(這樣可以去除對方收到消息后觸發(fā)回調(diào)接口,因為頁面本身的埋點數(shù)據(jù)接口已經(jīng)比較多了)
2、推送前還是加一層在線狀態(tài)的判斷,極限的情況下可能存在消息發(fā)了,用戶正好關(guān)了瀏覽器,不care,本身C端也有消息中心
3、用戶上線,ajax拉取各個業(yè)務(wù)線的消息,觸發(fā)去推送
至于加上redis隊列,一是為了去做兩套場景,就是即時推和延時推,二是防止推消息接口負(fù)載過大了,三是將推送的接口封裝解耦出來,只需要將要推送的動作都塞入隊列,設(shè)置多個進(jìn)程來消費,在消費中去推送消息,消費中也可以定制化的去做一些后續(xù)的動作(可能有埋點數(shù)據(jù),消息體封裝,賬戶快到期提醒等)
建議ajax發(fā)給webman的controller,controller通過webman/push通過websocket推送給客戶端,也是ws通訊。
controller寫業(yè)務(wù),websocket只做推送是最佳實踐。
如果非要業(yè)務(wù)都寫在ws服務(wù)里,可以用gatewayWorker。