前言
游戲開發中最復雜的模塊,沒有之一。其實我也不想寫這篇文章,怎奈框架代碼賣出去了,得給我的用戶一個交代。
網絡模塊都需要實現哪些功能呢?按我以往的開發經驗總結如下:
- 消息的正常發送與接收
- 長鏈接的斷線重連
- 消息發送失敗與嘗試
- 長鏈接的心跳處理
- 適應各種服務器定義的協議格式
- 適應各種數據傳輸格式
- 屏蔽長短鏈接的差異
- 長鏈接支持發送協議號與接收協議號不同的情況。
- 讓短鏈接也可以像長鏈接一樣更新數據。
有必要屏蔽長短鏈接嗎?
這個看需求吧
有沒有開發過程中將長鏈接改成短鏈接的情況呢?你客戶端不支持,服務器可是支持的。
如果一個團隊有很多開發人員,作為主程的你是否要屏蔽底層邏輯,提供統一的調用接口給其他開發人員使用呢?
如果你一個人做一款游戲,你就隨便來吧,隨便什么樣的方式只要你開心就好。
類圖
- 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,每個引擎實現的方式都不同。我只是從框架和封裝的角度整理一下具體的使用方式,其實細節的東西,你沒有遇到的時候也是沒辦法理解的,代碼里都是經驗。有想法的同學留言吧。
歡迎掃碼關注公眾號《微笑游戲》,瀏覽更多內容。
歡迎掃碼關注公眾號《微笑游戲》,瀏覽更多內容。