import { Egg_IfObserver as IfObserver } from "./Egg_IfObserver";
import { Egg_MsgCode as MsgCode} from "../Comm/Egg_MsgCode";
import { msg_def } from "../Protobuf/proto";
import { Egg_ResLogin } from "./Egg_ResLogin";
import { Egg_Tools } from "./Egg_Tools";
import Egg_OfflineArea from "../Others/Egg_OfflineArea";
export class Egg_NetManager
{
m_webSocket : WebSocket;
m_arObservers : Array<IfObserver>;
public static m_bManual : boolean;
public static m_inst;
private static m_resolve : any;
public static get _inst() : Egg_NetManager
{
if(!this.m_inst)
{
this.m_inst = new Egg_NetManager();
}
return this.m_inst;
}
//开启新的连接之前,调用初始连接信息,此调用会关闭先前的连接
public static Init(ip : string,port : number,bLogin : boolean)
{
let login = bLogin ? "true" : "false";
cc.sys.localStorage.setItem("ip",ip);
cc.sys.localStorage.setItem("port",port);
cc.sys.localStorage.setItem("login",login);
}
constructor()
{
let ip : string = cc.sys.localStorage.getItem("ip");
let port : number = cc.sys.localStorage.getItem("port");
if(ip == null || port == null)
{
console.error("mylog : ip or port is null");
return;
}
this.InitData();
this.InitSocket("ws://" + ip + ":" + port);
}
public IsConnected()
{
Egg_NetManager.m_resolve = null;
return new Promise((resolve,reject)=>{
Egg_NetManager.m_resolve = resolve;
});
}
private InitData()
{
this.m_arObservers = new Array<IfObserver>();
}
private InitSocket(serverIP : string)
{
let strBLogin = cc.sys.localStorage.getItem("login");
this.m_webSocket = new WebSocket(serverIP);
this.m_webSocket.binaryType = "arraybuffer";
this.m_webSocket.onopen = this.OnOpen.bind(this);
//登录和普通消息 消息头不一致,分开处理
if(strBLogin == "true")
{
this.m_webSocket.onmessage = this.OnMessageForLogin.bind(this);
}else
{
this.m_webSocket.onmessage = this.OnMessage.bind(this);
}
this.m_webSocket.onclose = this.OnClose.bind(this);
this.m_webSocket.onerror = this.OnError.bind(this);
}
private OnOpen()
{
Egg_NetManager.m_bManual = false;
console.log("[连接服务器成功]");
if(Egg_NetManager.m_resolve)
Egg_NetManager.m_resolve(true);
}
private OnMessage(event)
{
console.log("[服务器响应了]");
let data = new Uint8Array(event.data);
if(!data)
{
throw new console.error("event.data is null");
}
let msgHeader : msg_def.msg_header = msg_def.msg_header.decode(data);
console.log("接收到消息 = " + msgHeader.msgId);
this.NotifyAllObserver(msgHeader.msgId,msgHeader.payload);
}
//登录专用消息响应转发
private OnMessageForLogin(event)
{
console.log("[登录服务器响应了]");
let data = new Uint8Array(event.data);
if(!data)
{
throw new console.error("event.data is null");
}
let msgHeader : msg_def.login_msg_header = msg_def.login_msg_header.decode(data);
this.NotifyAllObserver(msgHeader.msgId,msgHeader.payload);
console.log("登录:接收到消息 = " + msgHeader.msgId);
}
private OnClose()
{
console.warn("[连接关闭]");
this.m_webSocket = null;
//连接断开了,点击任意区域重新加载
let offlineArea = cc.find("Canvas/OfflineArea");
if(offlineArea && !Egg_NetManager.m_bManual)
{
offlineArea.active = true;
let ctrl : Egg_OfflineArea = offlineArea.getComponent("Egg_OfflineArea");
ctrl.StartCountdown(10);
}
}
private OnError(event)
{
console.error("[连接异常]:" + event);
this.m_webSocket = null;
if(Egg_NetManager.m_resolve)
Egg_NetManager.m_resolve(false);
}
//添加网络消息观察者
public AttachObserver(observer : IfObserver)
{
this.m_arObservers.push(observer);
}
//移除观察者
public DetachObserver(observer : IfObserver)
{
for(let i = 0;i < this.m_arObservers.length;i++)
{
if(observer == this.m_arObservers[i])
{
this.m_arObservers.splice(i,1);
}
}
}
//通知观察者有事件到达
//注意:场景切换时,会出现多次附加观察者的情况,记得detach释放
public NotifyAllObserver(msgCode : MsgCode,data : Object)
{
this.m_arObservers.forEach(item => {
if(item)
{
item.OnReceive(msgCode,data);
}
});
}
//根据消息码发送(登录头不一致,故不可用于登录,登录用SendRaw)
public Send(msgCode : MsgCode,st : any,data : any)
{
let objPayload = null;
if(data != null)
{
objPayload = st.encode(data).finish();
}
let len = 0;
if(data != null) len = objPayload.length;
let msgHeader = msg_def.msg_header.create({
msgId : msgCode,
playerId : Egg_ResLogin.player_id,
token : Egg_ResLogin.token,
payloadLen : len,
payload : objPayload,
});
let objHeader = msg_def.msg_header.encode(msgHeader).finish();
this.m_webSocket.send(objHeader);
console.log("mylog 发送消息 " + msgCode);
}
//原始发送
public SendRaw(obj : any)
{
// console.log("登录服务器发送原始数据" + obj);
this.m_webSocket.send(obj);
}
//发送http请求
public Get(url : string,cb : CallableFunction,bAsync : boolean = true)
{
let xhr = cc.loader.getXMLHttpRequest();
xhr.open("GET",url,bAsync);
xhr.setRequestHeader("Content-Type","application/json;charset=UTF-8");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status <= 207)) {
cb(true,xhr.responseText);
}else
{
cb(false,"");
}
};
xhr.send();
}
//发送http请求
public Post(url : string,data : string,cb : CallableFunction,bAsync : boolean = true)
{
if(data == null) data = "";
let xhr = cc.loader.getXMLHttpRequest();
xhr.open("POST",url,bAsync);
xhr.setRequestHeader("Content-Type","multipart/form-data");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status <= 207)) {
cb(true,xhr.responseText);
}else
{
cb(false,"");
}
};
xhr.send(data);
}
//释放此网络管理器
public Destroy()
{
let webSocket = Egg_NetManager._inst.m_webSocket;
if(webSocket)
{
Egg_NetManager.m_bManual = true;
webSocket.close();
}
this.m_webSocket = null;
Egg_NetManager.m_inst = null;
cc.sys.localStorage.setItem("ip",null);
cc.sys.localStorage.setItem("port",null);
cc.sys.localStorage.setItem("login",null);
}
}