游戏开发中最复杂的模块,没有之一。其实我也不想写这篇文章,怎奈框架代码卖出去了,得给我的用户一个交代。 网络模块都需要实现哪些功能呢?按我以往的开发经验总结如下:
消息的正常发送与接收
长链接的断线重连
消息发送失败与尝试
长链接的心跳处理
适应各种服务器定义的协议格式
适应各种数据传输格式
屏蔽长短链接的差异
长链接支持发送协议号与接收协议号不同的情况。
让短链接也可以像长链接一样更新数据。
这个看需求吧 有没有开发过程中将长链接改成短链接的情况呢?你客户端不支持,服务器可是支持的。 如果一个团队有很多开发人员,作为主程的你是否要屏蔽底层逻辑,提供统一的调用接口给其他开发人员使用呢? 如果你一个人做一款游戏,你就随便来吧,随便什么样的方式只要你开心就好。
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,每个引擎实现的方式都不同。我只是从框架和封装的角度整理一下具体的使用方式,其实细节的东西,你没有遇到的时候也是没办法理解的,代码里都是经验。有想法的同学留言吧。
欢迎扫码关注公众号《微笑游戏》,浏览更多内容。