欢迎喜欢或者从事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)发送和接受我就不展示了,因为每个人的处理方式都不同.
如果有需要的话我再放出来
扫描二维码关注公众号,回复:
14664598 查看本文章