一個可遮蔽長短連結的網路模組

遊子陳發表於2020-08-06

前言

遊戲開發中最複雜的模組,沒有之一。其實我也不想寫這篇文章,怎奈框架程式碼賣出去了,得給我的使用者一個交代。
網路模組都需要實現哪些功能呢?按我以往的開發經驗總結如下:

  1. 訊息的正常傳送與接收
  2. 長連結的斷線重連
  3. 訊息傳送失敗與嘗試
  4. 長連結的心跳處理
  5. 適應各種伺服器定義的協議格式
  6. 適應各種資料傳輸格式
  7. 遮蔽長短連結的差異
  8. 長連結支援傳送協議號與接收協議號不同的情況。
  9. 讓短連結也可以像長連結一樣更新資料。

有必要遮蔽長短連結嗎?

這個看需求吧
有沒有開發過程中將長連結改成短連結的情況呢?你客戶端不支援,伺服器可是支援的。
如果一個團隊有很多開發人員,作為主程的你是否要遮蔽底層邏輯,提供統一的呼叫介面給其他開發人員使用呢?
如果你一個人做一款遊戲,你就隨便來吧,隨便什麼樣的方式只要你開心就好。

類圖

image.png

  1. Service 實現ServiceInterface介面負責遮蔽連結型別
  2. Message 負責封裝傳送和接收的訊息。
  3. MessageHander 負責編解碼處理。
  4. ServiceInfo 儲存伺服器資訊。例如 ip 埠,協議號對映等資訊。
  5. RemoteProxy 負責呼叫Service傳送訊息,接收Service返回的訊息並通過事件派發給監聽者。

關鍵程式碼

  1. ServiceInfo
    image.png
  2. ServiceInterface
    image.png
  3. Service
    image.png
  4. MessageHandler
    image.png
  5. Message
    image.png
  6. RemoteProxy
    image.png

如何使用呢?

  1. 定義一個類來處理連結的監聽
    image.png
  2. 定義一個地址和開發環境相關的資料類
    image.png
  3. 實現編解碼處理類
    image.png
  4. 定義協議號常量類
    image.png
  5. 定義一個連結
    image.png
  6. 使用方式
export default class LoginController extends LogicController {

    constructor(){
        super(LoginProxy.instance());
    }

    private static ins:LoginController;

    static instance():LoginController{
        if(!this.ins){
            this.ins = new LoginController();
        }
        return this.ins;
    }

    //註冊協議號與回撥函式
    getProtoList(){
        return [
            [NetConfig.OPEN,this.netOpen],
            [LoginProtocolIDs.LOGIN,this.loginRsp],
        ];
    }

    netOpen(){
        cc.log(' 連結成功 ')
        this.pushView('Prefab/LoginView','LoginView',null,ModuleManager.getLoader(),UIIndex.STACK)
    }
    //進入模組 先連結服務 當然也可以先彈出介面,再推送連結結果。
    intoLayer(){
        ModuleManager.setModuleID(ModuleID.LOGIN)
        //進入此模組,先進行連結操作,如果連結成功 會走loginRsp 函式
        this.remoteProxy.connect(new ServiceInfo(NetConfig.HTTP,AddressConfig.getAdress(AddressConfig.LOGIN,0)));
    }

    // 點選登陸按鈕傳送請求。
    loginReq(name:string){
        cc.log(" loginReq ",name);
        this.sendMessage(LoginProtocolIDs.LOGIN,{name:name,channel:'crazy'});
    }

    //登陸成功
    loginRsp(msg:ReceiveMessage){
        cc.log(" loginRsp msg ",msg);
        //由於伺服器已經關閉,所以不會被呼叫,正常內容返回時會走這裡。
    }

}

結語

細節程式碼太多了,如果都貼上上來無法忍受。其實網路那些事論壇裡已經有人說的很詳細了。使用方式也很多,就好像都是用xxgl,每個引擎實現的方式都不同。我只是從框架和封裝的角度整理一下具體的使用方式,其實細節的東西,你沒有遇到的時候也是沒辦法理解的,程式碼裡都是經驗。有想法的同學留言吧。

歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多內容。

微信圖片_20190904220029.jpg

歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多內容。

相關文章