[CocosCreator]封装WebSocket网络管理器(包含心跳)

       欢迎喜欢或者从事CocosCreator开发的小伙伴请加入我的大家庭CocosCreator游戏开发Q群:26855530

本文分两个管理类:

1.WebSocket(长连接)管理器

2.心跳管理器

WebSocket(长连接)管理器:

import SysLog from "../utils/SysLog";
import ServerConfig from "../common/ServerConfig";
import HeartBeatManager from "./HeartBeatManager";
import MsgHandler from "./MsgHandler";
import GameData from "../data/GameData";
import MsgSender from "./MsgSender";
import SysDate from "../data/SysDate";
import GameFunctionUtil from "../utils/GameFunctionUtil";
import GamePublicUtil from "../utils/GamePublicUtil";

class NetworkManager {
    _socket: WebSocket = null;  //当前的webSocket的对象
    init() { //初始化
        SysLog.info("WebSocket初始化完成");
    }

    connectToServer(a?, b?) {
        //清空以前socket的绑定
        if (this._socket) {
            this._socket.onopen = undefined;
            this._socket.onmessage = undefined;
            this._socket.onclose = undefined;
            this._socket.onerror = undefined;
        }

        this._socket = new WebSocket(ServerConfig.game_subPoint);
        SysLog.debug("websocket:" + ServerConfig.game_subPoint);
        this._socket.binaryType = "arraybuffer"; // We are talking binary
        this._socket.onopen = () => {
            GamePublicUtil.initBaseProto();

            //发送首次登陆
            MsgSender.send_LoginUser(GameData.userInfo.id);

            //开始心跳
            HeartBeatManager.start();

            SysLog.info("Websocket Successfully Connected");
            cc.game.dispatchEvent(new cc.Event.EventCustom("wsOpen", false));
        };

        this._socket.onclose = (event) => {
            SysLog.info("Socket onclose", event.reason);
            if (SysDate.Public_Ready_Socket == false) {
                SysDate.Public_Ready_Socket = true;
            } else {
                GameFunctionUtil.getInstance().showSimpleTips("连接已中断");
            }
        };

        this._socket.onerror = (event) => {
            SysLog.info("Socket onerror", event);
            GameFunctionUtil.getInstance().showSimpleTips("连接发生异常,游戏即将结束");
            cc.director.preloadScene('LoginScene', function () {
                cc.director.loadScene('LoginScene');
            });
        };

        this._socket.onmessage = (event) => {
            this._onMessage(event["data"]);
        };
    }

    connect(callback?, num?) {
        if (this._socket && cc.sys.isObjectValid(this._socket)) {
            if (this._socket.readyState > WebSocket.OPEN) {
                this._socket.close();
                this.connectToServer(callback, num);
            } else {
                if (this.isOpen() === true) {
                    HeartBeatManager.start();
                    if (callback) callback(num);
                }
            }
        } else {
            this.connectToServer(callback);
        }
    }

    close() {
        if (this._socket && cc.sys.isObjectValid(this._socket)) {
            SysDate.Public_Ready_Socket = false;
            this._socket.close();
            SysLog.info("Successfully Close Connected");
        } else {
            SysLog.info("NO Socket");
        }
    }

    _onMessage(data) {
        MsgHandler.Unmarshal(new Uint8Array(data));
    }

    sendProtobuf(msgName, dataObj) {
        if (this.isOpen()) {
            let buffer = MsgHandler.Marshal(msgName, dataObj); //Proto buffer
            this._socket.send(buffer);
        } else {
            SysLog.error("WebSocket do not Open!!!")
        }
    }

    isOpen() {
        if (this._socket && cc.sys.isObjectValid(this._socket)) {
            return this._socket.readyState === WebSocket.OPEN;
        } else {
            return false;
        }
    }

    isConnecting() {
        if (this._socket && cc.sys.isObjectValid(this._socket)) {
            return this._socket.readyState === WebSocket.CONNECTING;
        } else {
            return false;
        }
    }

    //心跳重连入口
    heartCall() {
        this.connect(() => {
            SysLog.info("心跳超时 webSocket Reconnect!");
        });
    }
}

export default new NetworkManager();

心跳管理器:

import SysLog from "../utils/SysLog";
import NetworkManager from "./NetworkManager";
import GameData from "../data/GameData";
import MsgSender from "./MsgSender";

/**
 * 心跳管理器
 */
class HeartBeatManager {
    timeOut: number = 5000; //心跳频率 5秒
    private timeObj: any = null;
    private serverTimeObj: any = null;

    init() { //初始化
        SysLog.info("HeartBeat 初始化完成");
    }

    //启动
    start() {
        //清除延时器
        this.close();
        this.timeObj = setTimeout(() => {
            //TODO 保险需要判断userId是否可读取,否则应返回登录界面
            //发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数

            MsgSender.send_Ping(GameData.userInfo.id);

            //定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接
            this.serverTimeObj = setTimeout(() => {
                NetworkManager.heartCall();
            }, this.timeOut);
        }, this.timeOut)
    }

    //关闭
    close() {
        this.timeObj && clearTimeout(this.timeObj);
        this.serverTimeObj && clearTimeout(this.serverTimeObj);
    }
}

export default new HeartBeatManager();

PS:

具体的消息提(message)发送和接受我就不展示了,因为每个人的处理方式都不同.

如果有需要的话我再放出来

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值