大家好,我是dandyhuang肄满。記憶中稠歉,從大學接觸編程開始,就覺得qq怒炸,wx這些聊天很神奇阅羹。就一直想弄明白它是怎么做的。直到畢業(yè)后捏鱼,工作了一段時間這是根im相關(guān)的知識穷躁。golang中im鼻祖應該是毛老師(毛劍)的goim了因妇。本期咱們還不做改代碼分析猿诸,我們暫時簡單的分析一下gim的實現(xiàn)。
gim
gim中址芯,設(shè)計還是比較清晰的窜觉,花幾天時間,基本上就搞清楚了旬陡。主要分為connect语婴、logic、business三大模塊匿醒,內(nèi)部通過websocket缠导、tcp、grpc協(xié)議進行通訊憋他。思想理念和goim基本一致嫡意。涉及的中間件很少,所以建議看完gim再去看goim此迅,會更容易理解一些旧巾。但gim還有很多缺陷,未完善坎怪,如果要使用到生產(chǎn)環(huán)境廓握,還需要在做一定的修改嘁酿。
gim.png
- connect
維持與客戶端的TCP和WebSocket長連接闹司,心跳沐飘,以及TCP拆包粘包。通過connect發(fā)送消息編解碼數(shù)據(jù)借卧。如a筛峭、b同時和connect創(chuàng)建連接。a向b發(fā)送數(shù)據(jù)滨达,通過先發(fā)送給connect俯艰,connect在中轉(zhuǎn)到b锌订。 - logic
設(shè)備信息辆飘,好友信息,群組信息管理蜈项,消息轉(zhuǎn)發(fā)邏輯 - business
一個簡單的業(yè)務服務器服務紧卒,可以根據(jù)自己的業(yè)務需求,進行擴展,但是前提是轴总,你的業(yè)務服務器實現(xiàn)了business.int.proto接口
設(shè)備注冊和用戶登錄
login.png
- 當設(shè)備和用戶未注冊時博个,需要調(diào)用注冊接口⊥ぃ客戶端可以根據(jù)自身設(shè)備id和用戶id判斷是否注冊完成
- 當注冊成功,向
connect
發(fā)起ws/tcp鏈接养葵。connect
會校驗鏈接的設(shè)備是否合法瘩缆,失敗關(guān)閉連接庸娱。成功返回登錄成功消息。 -
connect
創(chuàng)建設(shè)備和connect
句柄映射關(guān)系熟尉。 - 創(chuàng)建協(xié)程斤儿,發(fā)送心跳包,維持ws和tcp之間的連接往果。conn.WS.SetReadDeadline和gn.WithTimeout(11*time.Minute)陕贮。心跳周期需要小于服務端連接的時間
- 創(chuàng)建協(xié)程肮之,獲取離線消息同步信息
- 創(chuàng)建協(xié)程戈擒,獲取訂閱獲取廣播消息
發(fā)送消息
sendmsg.png
- client A發(fā)送grpc消息給logic服務筐高。
- logic校驗A的信息和要發(fā)送的用戶B凯傲。
- 持久化信息,獲取用戶B登錄的所有設(shè)備冰单,并將信息發(fā)送給Connect
- Connect獲取對應要發(fā)送的設(shè)備的Conn句柄,發(fā)送websocket/tcp信息給B
大家可以添加我的wx一起探討
我是dandyhuang_涵卵,碼字不易,點個小贊轿偎,只希望大家能更加明白