天天看點

伺服器主邏輯代碼的重構

    不知道前主程是處于什麼目的,總之我接手這套程式的時候,出現了超級多的問題,也發現了超級多的問題。

     比如說吧,接受網絡消息邏輯是線程獨立的,而發送消息給用戶端缺阻塞在了邏輯線程裡面;原本可以放在一個程序裡面處理的邏輯,卻分散在了四個程序裡面去處理,導緻我完成一個功能,大部分時間要話費了程序之間的玩家資訊的同步上面,在我無法忍受的情況下,我終于是用nio将網絡底層從新寫了,而且将四個程序合并,但是在很多邏輯上還是盡量保持了和原邏輯處理的相容!

      先說說這個重構的底層吧!

     我們看下最重要的clienthandle類,主要處理每個連接配接的收發資料的!

  包含socketchannel對象不用說了,reader和writer是用來做消息收發的緩沖的,因為伺服器廣播的壓力會大一些,是以将writer的大小設定為reader的4倍,當然這個可以調整。

     writequeue是用來存儲需要發送給用戶端的bytebuffer,每次在這個連結可以寫資料的時候,就将writequeue裡面存儲的資料轉移到writer中,并且一次發送,減少了writer的系統調用次數。bytebuffer的結構簡單說下,不同于java.nio.bytebuffer,而是自己封裝的一個消息解析器,給出源代碼

  下面看下 clienthandle的可讀邏輯:

  依次将資料讀入到reader中,并且按照lc(l表示長度,c表示内容)結構将reader中的資料解析成一個個bytebuffer對象處理。下面是createbuffer函數和processdata函數:

  這裡要注意,1:解析reader中的消息一定要做容錯處理;2:将解析的待處理包放到玩家身上,讓玩家自己處理!

     發送函數的處理:

  發送函數的處理相對複雜些,首先要做的就是每個連接配接的發送函數每100ms(可以調整)觸發一次,每次觸發時候,要将待發送的資料包bytebuffer填充到writer緩沖區,然後一次發送!

     管理協調這些連結的建立和處理都是使用了java nio的selector結構,具體的代碼就不貼出來了,想要的可以聯系我,需要注意的有兩點,1:對于空閑連接配接的處理,2:對于發送資料的處理

     大緻講完了網絡線程,那麼講一講主邏輯線程,邏輯線程采用線程綁定地圖的設計;在伺服器啟動之時,啟動n(可以調整)個地圖線程,每個地圖線程綁定n(可以調整)個地圖,這n個地圖上的所有玩家的邏輯處理,都有地圖所線上程來處理,具體處理方式:

     地圖線程的主邏輯:

  場景scene的心跳函數:

  玩家的心跳函數:

  好了,大概的伺服器的主邏輯就這些了,是不是精簡小巧。晚上的時候還做了一下廣播壓力測試,效果還不錯!

     歡迎大家提出寶貴意見!