基於 websocket 實現的 im 實時通信案例

分享利用 redis 訂閱與發佈特性,巧妙的現實高性能im系統。爲表誠意,先貼源碼地址:https://github.com/2881099/im前端

下載源碼後的運行方法:ios

運行環境:.NETCore 2.1 + redis-server 2.8git

下載Redis-x64-2.8.2402.zip,點擊 start.bat 運行;或者修改 imServer、web 下面 appsettings.json redis 配置,指向可用的redis-servergithub

cd imServer && dotnet run --urls="http://0.0.0.0:6001"web

cd web && dotnet run --urls="http://0.0.0.0:5555"redis

打開多個瀏覽器,訪問 http://127.0.0.1:5555 發送羣消息算法

設計思路

socket選型

最二的辦法是瀏覽器端使用websocket,其餘端socket,這麼混亂的設計最終將很是難維護。json

因此強烈建議全部端都使用websocket協議,adorid/ios/h5/小程序所有支持websocket客戶端。小程序

業務與通信協議

im系統通常涉及【個人好友】、【個人羣】、【歷史消息】等等。。後端

那麼,imServer與業務方(web)該保持何種關係呢?

用戶A向好友B發送消息,分析一下:

  • 須要判斷B是否爲A好友;
  • 須要判斷A是否有權限;
  • 等等。。

諸如此類業務判斷會很複雜,咱們試想一下,若是使用imServer作業務協議,它是否是會變成巨無霸難以維護。

又假如獲取歷史記錄,難道客戶端要先websocket.send('gethistory'),再在onmessage裏定位回調處理?

這樣作十分之二。。。


咱這樣設計,全部用戶的主動行爲走業務方(web),imServer只負責即時消息推送。什麼意思?

用戶A向好友B發送消息:客戶端請求業務方(web)接口,由業務方(web)後端向imServer發起推送請求,imServer收到指令後,向前端用戶B的websocket發送數據,用戶B收到了消息。

獲取歷史消息:客戶端請求業務方(web)接口,返回json(歷史消息)

回執:用戶A如何知道消息發送狀態(成功或失敗或不在線)?imServer端向用戶B發送消息時,把狀態以消息的方式推給用戶A便可(按上面的邏輯),具體請看源碼吧。。。

web通知imServer性能優化

採用消息隊列,redis的發佈訂閱最爲輕量。

實現多節點部署

單個imServer實例支持多少websocket鏈接,幾百個沒問題吧,好。。。

若是系統在線用戶有1萬人,怎麼辦???

能夠根據id的hash分區,好比部署4個imServer:

  • imServer1 訂閱 redisChanne1
  • imServer2 訂閱 redisChanne2
  • imServer3 訂閱 redisChanne3
  • imServer4 訂閱 redisChanne4

業務方(web)端根據接收方的id的hash分區算法,定位到對應的redisChannel,這樣publish就能夠將消息定位到相應的imServer了

相關文章
相關標籤/搜索