Go 語言 socket 框架之心跳處理

【導讀】本文介紹了 socket 心跳處理的設計和實現。

前言:

本次我們來講解怎麼在自己的框架裏面增加心跳處理。已經把所有代碼整合了,希望給個星星支持一下 GitHub - mistaker/microSocket: 同時支持 socket 和 websocket 的框架。

心跳處理的必要性:

服務端需要同時處理上千甚至上萬的客戶端的連接,所以每個連接資源都是很寶貴的,當客戶端斷開連接的時候服務端應該及時移除該連接。
正常情況下,客戶端斷開連接的時候,會和服務端進行四次揮手,服務端就會知道這個連接 已經不能用了優雅的退出監聽消息。但是總會有意外,比如客戶端忽然斷網了,沒電了,這個時候客戶端肯定不可能按照流程和 服務端進行揮手,不知道消息的 服務端還傻傻的在哪兒等着,不知道客戶端早就走了
這個時候 心跳包就很完美的解決了此問題。客戶端和服務端約定好每隔一段時間 就會發消息,如果服務端每過一段時間沒有收到客戶端 的心跳消息 就說明 客戶端出事了,服務端就刪除此連接,確保 資源最大化。
一般心跳包就是 符合該協議的 最小包

實現思路:

一般的 go 語言框架都是一個連接單獨開一個協程 去處理讀取超時問題,我承認協程是很廉價,但是總不至於這麼浪費吧,當協程數量多到一定程度的時候,協程之間的調度也是一個很大的 消耗,所以我沒有采用這種思路。
經過我的苦思冥想終於被我想到了自認爲比較好的方法,實現了,一個協程 進行 心跳檢測。

代碼實現:

//這是每個連接對象 每次接收到消息就會更新times爲當前時間戳
type Session struct {
    Id    uint32
    Con   net.Conn
    times int64
    lock  sync.Mutex
}
//這是更新時間函數
func (this *Session)UpdateTime(){
    this.times = time.Now().Unix()
}
//---------------------------------------------------SESSION管理類------------------------------------------------------

type SessionM struct {
    sessions map[uint32]*Session
    num      uint32
    lock     sync.RWMutex
    isWebSocket bool
    ser     *Msf
}
//心跳檢測   每秒遍歷一次 查看所有sess 上次接收消息時間  如果超過 num 就刪除該 sess
func (this *SessionM)HeartBeat(num int64){
    for {
        time.Sleep(time.Second)
        for i,v:= range this.sessions{
            if time.Now().Unix() - v.times > num {
                this.DelSessionById(i)
            }
        }
    }
}

當框架啓動的時候就開一個協程

go this.SessionMaster.HeartBeat(2)

每次接收到新的消息的時候就更新接收時間

//更新接收時間
sess.UpdateTime()

以上是核心代碼。細節可以看 https://github.com/mistaker/microSocket

轉自:

jianshu.com/p/d7d6ab53a1ea

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Ylve72YzEVbZFTHJyYDLqw