Egret官方提供了一个Websocket的库,可以让我们方便的和服务器长连接交互。
标题写的时候自定义websocket的协议格式。解释一下,不是说我们去动websocket本身的东西,我们是在websocket的传输内容里面约定一套服务器和客户的交互格式。
捋一下思路:
- 选择序列化的方式
- 约定一个交互格式
- 封装一个简单的NetMgr(网络管理类)
选择序列化方式:
目前主流的序列化方式一般就三种 xml json protobuf,经过考虑,我决定选择json,原因是:1.对复杂的格式支持比protobuf好。2.比xml更节约流量。3.因为选择的时候TypeScript,所以json序列化更方便,我看egret论坛有反应protobuf在微信小程序中有问题。所以综合一下,就选择json吧。
约定一个交互格式:
格式就三个字段:1.cmd :命令 2. data 数据 3. CmdType:命令类型
class Protocol<T> { public cmd: string; public data: T; public cmdType: CMDTYPE; } enum CMDTYPE { RECHARGE, NET, OTHER }
封装一个简单的NetMgr:
封装NetMgr这个类主要是想把游戏逻辑和基础的网络操作部分屏蔽,通过Egret的事件机制来传递网络数据到界面层。发送数据给服务器,也只操作NetMgr。不会直接接触websocket。
简单的事件类封装
class NetEvent extends egret.Event { public cmd: string = "NetEvent"; public data: any; public constructor(type: string, bubbles: boolean = false, cancelable: boolean = false) { super(type, bubbles, cancelable); } }
NetMgr类
// TypeScript file /** * 网络管理类 */ class NetMgr extends egret.DisplayObject { private socket: egret.WebSocket = new egret.WebSocket(); static net: NetMgr; constructor() { super(); } public static GetInstance(): NetMgr { if (this.net == null) this.net = new NetMgr(); return this.net; } public StartSocket(serverip: string, port: number): void { if (this.socket.connected) return; this.socket.addEventListener(egret.ProgressEvent.SOCKET_DATA, this.onReceiveMessage, this); this.socket.addEventListener(egret.Event.CONNECT, this.onSocketOpen, this); this.socket.addEventListener(egret.IOErrorEvent.IO_ERROR, this.IOError, this); this.socket.addEventListener(egret.Event.CLOSE, this.Close, this); this.socket.connect(serverip, port) } public GetStatus(): boolean { return this.socket.connected; } onReceiveMessage(): void { console.log("接收到消息:"); var msg = this.socket.readUTF(); console.log(msg); let protocol: Protocol<any> = JSON.parse(msg); // if (protocol.cmd) { try { let event = new NetEvent(NetEvent.Net); event.cmd = protocol.cmd; event.data = protocol; this.dispatchEvent(event) } catch (error) { console.error("网络事件:" + protocol.cmd + "-处理错误") } } Close(): void { console.log("连接关闭") } onSocketOpen(): void { console.log("网络连接成功"); } IOError(): void { console.log("网络连接断开") } public Emit<T>(cmd: string, data: T): void { if (this.socket.connected) { let protocol = new Protocol<T>(); protocol.cmd = cmd; protocol.data = data; this.socket.writeUTF(JSON.stringify(protocol)); } } }
简单的网络操作和序列化就这样了,后面还有断网重连之类的,就后面再优化。(我一般做东西都是先实现,再优化)
如何使用呢??
1.接收服务器的数据
NetMgr.GetInstance().addEventListener(NetEvent.Net, (e: NetEvent) => { console.log("接受到网络派发的事件" + e.data) }, this)
2.给服务器发送数据
let demo = new TestDemo(); demo.Data = "wocao"; NetMgr.GetInstance().Emit<TestDemo>("serverAction", demo);
好了,这块内容就到这里了