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