美文网首页
websocket连接示例备份

websocket连接示例备份

作者: Albert_d37d | 来源:发表于2021-11-17 08:57 被阅读0次

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);

    }

}

相关文章

网友评论

      本文标题:websocket连接示例备份

      本文链接:https://www.haomeiwen.com/subject/gbqltrtx.html