一個可屏蔽長短鏈接的網絡模塊


前言

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

  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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM