this.socket = new egret.WebSocket();
this.socket.addEventListener(egret.Event.CONNECT, this.onConnect, this);
this.socket.addEventListener(egret.Event.CLOSE, this.onClose, this);
this.socket.addEventListener(egret.IOErrorEvent.IO_ERROR, this.onError, this);
this.socket.addEventListener(egret.ProgressEvent.SOCKET_DATA, this.onMessage, this);
//二进制
this.socket.type = egret.WebSocket.TYPE_BINARY;
private timeOutTimer: egret.Timer;
public connect() {
if (!this.timeOutTimer)
this.timeOutTimer = new egret.Timer(8000);
this.timeOutTimer.once(egret.TimerEvent.TIMER_COMPLETE, this.onTimeOut, this);
this.socket.connect("192.168.0.105", 8084);
}
private onTimeOut() {
console.log("time out");
this.socket.close();
//返回登录界面
}
//key:消息ID value:处理函数
private handleMap: { [key: number]: Function } = {};
//初始化时将各个模块的消息分模块的注册到 handleType中
private register(type: number, handler: Function) {
if (!handler) return;
if (this.handleMap[type]) {
console.warn(this, type + " has already been registed to GameSocket");
}
this.handleMap[type] = handler;
}
//注销消息
private unRegister(type: number): void {
if (type in this.handleMap) {
delete this.handleMap[type];
}
else {
console.error(this, "Cannot find the type: " + type);
}
}
//进行消息分配
private onMessage() {
var msg = new egret.ByteArray();
this.socket.readBytes(msg);
msg.position = 0;
while (msg.readAvailable >= 4) {
var len = msg.readShort();
if (len <= 0) {
console.log("wrong msg len!");
}
if (msg.readAvailable >= len - 2) {
var cmd: any = msg.readShort();
var pos = msg.position;
var isHandle = this.excuteHandle(cmd, msg);
msg.position = pos + len - 4;
} else {
msg.position -= 2;
break;
}
}
}
//执行相应的消息处理函数
private excuteHandle(cmd: number, msg) {
if (cmd in this.handleType)
this.handleType[cmd](msg);
else
console.warn(this, "No handle was found for type: " + cmd);
}
}
将所有的消息根据模块进行划分,然后进行模块管理,比如在前期登录的时候用的消息接口,进入游戏不用了 可以注销掉,以减少一些内存
//批量注册
public registerMessageReciever(reciever: AbstractMessageReceiver): void {
var dic: { [key: number]: Function } = reciever.collectObservers();
for (var key in dic) {
this.register(Number(key), dic[key]);
}
}
public removeMessageReciver(reciever: AbstractMessageReceiver): void {
var dic: any = reciever.collectObservers();
for (var key in dic) {
this.unRegister(parseInt(key));
}
}
每个模块继承AbstractMessageReceiver生成自己的消息队列
private cmdObservers: { [key: number]: Function } = {};
private hasCollected: boolean = false;
/**注册命令列表**/
protected registObservers(): void {
throw new Error("collectObservers must be implemented by subclass");
}
/**获取命令观察列表**/
public collectObservers(): any {
if (!this.hasCollected) {
this.registObservers();
this.hasCollected = true;
}
return this.cmdObservers;
}
/**
* 注册命令及对应处理函数
*/
protected register(cmd: number, handler: Function): void {
if (cmd in this.cmdObservers) {
//egret.log("Warning " + cmd + " has already been registed");
}
if (handler == null) {
throw new Error("Cannot registe a null hanlder")
}
this.cmdObservers[cmd] = handler;
}
用来管理预处理模块的所有GC(服务器到客户端)消息,当初始化游戏的时候可以将该模块加载到MessageManager,当进入游戏可以将该模块注销掉,该模块的消息将不再监听,也减少一点内存
class PreTreatGCMessage extends AbstractMessageReceiver {
protected registObservers(): void {
//注册消息的处理函数
this.register(511, this.onHandShock);
this.register(1203, this.onLoginSuccess);
}
//握手消息
private onHandShock() {
PreTreatCGMessage.CG_LOGIN();
}
//登录成功
private onLoginSuccess() {
console.log("登录成功");
}
}
管理所有预处理模块的所有CG(客户端到服务器)消息
class PreTreatCGMessage {
public static CG_HAND_SHOCK() {
var body = new egret.ByteArray();
MessageManager.ins().sendPacket(510, body);
}
public static CG_LOGIN() {
var body = new egret.ByteArray();
body.writeUTF("1");
body.writeUTF("1");
body.writeUTF("");
body.writeBoolean(false);
body.writeInt(1);
body.writeUTF("mozilla/5.0 (windows nt 10.0; wo");
body.writeUTF("mozilla/5.0 (windows nt 10.0; wo");
body.writeUTF("-1");
body.writeUTF("1.0.0");
body.writeUTF("zh_CN");
MessageManager.ins().sendPacket(1201, body);
}
}
继承SingleTon就可以实现基类不用再子类再写任何代码
可以将MessageManger继承自SingleTon
class Singleton {
public static ins(this: new (...args) => T): T {
if (!(this).instance)
(this).instance = new this();
return (this).instance;
}
//销毁单例
public static detory(this: new (...args) => T) {
if ((this).instance) {
delete (this).instance;
(this).instance = null;
}
}
}