前言
遊戲開發中最複雜的模組,沒有之一。其實我也不想寫這篇文章,怎奈框架程式碼賣出去了,得給我的使用者一個交代。
網路模組都需要實現哪些功能呢?按我以往的開發經驗總結如下:
- 訊息的正常傳送與接收
- 長連結的斷線重連
- 訊息傳送失敗與嘗試
- 長連結的心跳處理
- 適應各種伺服器定義的協議格式
- 適應各種資料傳輸格式
- 遮蔽長短連結的差異
- 長連結支援傳送協議號與接收協議號不同的情況。
- 讓短連結也可以像長連結一樣更新資料。
有必要遮蔽長短連結嗎?
這個看需求吧
有沒有開發過程中將長連結改成短連結的情況呢?你客戶端不支援,伺服器可是支援的。
如果一個團隊有很多開發人員,作為主程的你是否要遮蔽底層邏輯,提供統一的呼叫介面給其他開發人員使用呢?
如果你一個人做一款遊戲,你就隨便來吧,隨便什麼樣的方式只要你開心就好。
類圖
- Service 實現ServiceInterface介面負責遮蔽連結型別
- Message 負責封裝傳送和接收的訊息。
- MessageHander 負責編解碼處理。
- ServiceInfo 儲存伺服器資訊。例如 ip 埠,協議號對映等資訊。
- RemoteProxy 負責呼叫Service傳送訊息,接收Service返回的訊息並通過事件派發給監聽者。
關鍵程式碼
- ServiceInfo
- ServiceInterface
- Service
- MessageHandler
- Message
- RemoteProxy
如何使用呢?
- 定義一個類來處理連結的監聽
- 定義一個地址和開發環境相關的資料類
- 實現編解碼處理類
- 定義協議號常量類
- 定義一個連結
- 使用方式
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,每個引擎實現的方式都不同。我只是從框架和封裝的角度整理一下具體的使用方式,其實細節的東西,你沒有遇到的時候也是沒辦法理解的,程式碼裡都是經驗。有想法的同學留言吧。
歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多內容。
歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多內容。