first commit
This commit is contained in:
12
assets/scripts/network/http.meta
Normal file
12
assets/scripts/network/http.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "7d7f36b8-59d8-48e1-89d5-549e60e569ea",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
80
assets/scripts/network/http/HttpInvoke.ts
Normal file
80
assets/scripts/network/http/HttpInvoke.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { _decorator } from 'cc';
|
||||
import { NetEvent } from "../socket/NetInterface";
|
||||
import { EventMgr } from '../../utils/EventMgr';
|
||||
|
||||
|
||||
export enum HttpInvokeType {
|
||||
GET,
|
||||
POST
|
||||
}
|
||||
|
||||
|
||||
export class HttpInvoke {
|
||||
|
||||
protected _receiveTime: number = 15000; // 多久没收到数据断开
|
||||
protected _name:string = "";
|
||||
protected _otherData:any = null;
|
||||
|
||||
|
||||
public init(name:string,_otherData:any = null):void{
|
||||
this._name = name;
|
||||
this._otherData = _otherData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private onComplete(data:any):void{
|
||||
var json = {};
|
||||
if(data){
|
||||
try {
|
||||
json = JSON.parse(data.responseText);
|
||||
} catch (e) {
|
||||
console.log("onComplete--e:",e)
|
||||
}
|
||||
}
|
||||
EventMgr.emit(this._name, json,this._otherData);
|
||||
EventMgr.emit(NetEvent.ServerRequestSucess,json);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public doSend(url:string,params:any,type:HttpInvokeType):void{
|
||||
var self = this;
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.timeout = this._receiveTime;
|
||||
|
||||
|
||||
console.log("doSend:",url,params,type)
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4) {
|
||||
console.log("onreadystatechange:",xhr.responseText);
|
||||
if (xhr.status >= 200 && xhr.status < 400) {
|
||||
self.onComplete(xhr);
|
||||
} else {
|
||||
self.onComplete(null);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
xhr.ontimeout = function () {
|
||||
console.log("xhr.ontimeout");
|
||||
self.onComplete(null);
|
||||
};
|
||||
xhr.onerror = function (e) {
|
||||
console.log("xhr.onerror:", xhr.readyState, xhr.status, e);
|
||||
self.onComplete(null);
|
||||
};
|
||||
|
||||
|
||||
if(type == HttpInvokeType.GET){
|
||||
url +="?"+ params;
|
||||
xhr.open("GET",url , true);
|
||||
xhr.send();
|
||||
}else if(type == HttpInvokeType.POST){
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
|
||||
xhr.send(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
assets/scripts/network/http/HttpInvoke.ts.meta
Normal file
11
assets/scripts/network/http/HttpInvoke.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "113518b9-08ac-4655-b974-09714c4ac40a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
35
assets/scripts/network/http/HttpManager.ts
Normal file
35
assets/scripts/network/http/HttpManager.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { _decorator } from 'cc';
|
||||
import { HttpInvoke,HttpInvokeType } from "./HttpInvoke";
|
||||
|
||||
export class HttpManager {
|
||||
private static _instance: HttpManager = null;
|
||||
public static getInstance(): HttpManager {
|
||||
if (this._instance == null) {
|
||||
this._instance = new HttpManager();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
|
||||
protected _url:string = "";
|
||||
public setWebUrl(url:string):void{
|
||||
if(this._url == "" || this._url != url){
|
||||
this._url = url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public doGet(name:string,apiUrl:string,params:any,otherData:any = null):void{
|
||||
var invoke = new HttpInvoke();
|
||||
invoke.init(name,otherData);
|
||||
invoke.doSend(this._url + apiUrl,params,HttpInvokeType.GET);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public doPost(name:string,apiUrl:string,params:any,otherData:any = null):void{
|
||||
var invoke = new HttpInvoke();
|
||||
invoke.init(name,otherData);
|
||||
invoke.doSend(this._url + apiUrl,params,HttpInvokeType.POST);
|
||||
}
|
||||
}
|
||||
11
assets/scripts/network/http/HttpManager.ts.meta
Normal file
11
assets/scripts/network/http/HttpManager.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e31d2dab-7625-4555-b2a3-cebd6923f8da",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
12
assets/scripts/network/socket.meta
Normal file
12
assets/scripts/network/socket.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "62ddfc3f-f527-43d7-90bd-518e0b049509",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
48
assets/scripts/network/socket/NetInterface.ts
Normal file
48
assets/scripts/network/socket/NetInterface.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
export type NetData = (string | ArrayBufferLike | Blob | ArrayBufferView);
|
||||
|
||||
export class RequestObject {
|
||||
public json: any = null; // 请求的json
|
||||
public rspName: string = ""; // 接口名
|
||||
public autoReconnect: number = 0; // -1 永久重连,0不自动重连,其他正整数为自动重试次数
|
||||
public seq:number = 0; // 消息的序号
|
||||
public sended:boolean = false; // 是否发送
|
||||
public otherData:any = {};
|
||||
public startTime:number = 0
|
||||
|
||||
public destroy():void{
|
||||
this.json = null;
|
||||
this.rspName = "";
|
||||
this.autoReconnect = 0;
|
||||
this.seq = 0;
|
||||
this.sended = false;
|
||||
this.otherData = {};
|
||||
this.startTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Socket接口
|
||||
export interface ISocket {
|
||||
onConnected: (event) => void; // 连接回调
|
||||
onMessage: (msg: NetData) => void; // 消息回调
|
||||
onJsonMessage: (msg: NetData) => void; // 消息回调
|
||||
onError: (event) => void; // 错误回调
|
||||
onClosed: (event) => void; // 关闭回调
|
||||
|
||||
connect(options: any); // 连接接口
|
||||
send(buffer: NetData); // 数据发送接口
|
||||
close(code?: number, reason?: string); // 关闭接口
|
||||
}
|
||||
|
||||
|
||||
// 请求对象
|
||||
export class NetEvent {
|
||||
public static ServerTimeOut:string = "ServerTimeOut";
|
||||
public static ServerConnected:string = "ServerConnected";
|
||||
public static ServerHandShake:string = "ServerHandShake";
|
||||
public static ServerCheckLogin:string = "ServerCheckLogin";
|
||||
public static ServerRequesting:string = "ServerRequesting";
|
||||
public static ServerRequestSucess:string = "ServerRequestSucess";
|
||||
}
|
||||
11
assets/scripts/network/socket/NetInterface.ts.meta
Normal file
11
assets/scripts/network/socket/NetInterface.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e98e24b5-8b3c-4d33-b19e-e255ec74757f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
40
assets/scripts/network/socket/NetManager.ts
Normal file
40
assets/scripts/network/socket/NetManager.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { _decorator } from 'cc';
|
||||
import { NetNode, NetConnectOptions } from "./NetNode";
|
||||
|
||||
export class NetManager {
|
||||
private static _instance: NetManager = null;
|
||||
protected _netNode: NetNode = null;
|
||||
public static getInstance(): NetManager {
|
||||
if (this._instance == null) {
|
||||
this._instance = new NetManager();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
constructor(){
|
||||
this._netNode = new NetNode();
|
||||
this._netNode.init();
|
||||
}
|
||||
|
||||
public connect(options: NetConnectOptions) :void{
|
||||
this._netNode.connect(options);
|
||||
}
|
||||
|
||||
public send(send_data: any, otherData:any = {},force: boolean = false) :void{
|
||||
if(send_data.seq == undefined){
|
||||
send_data.seq = 0;
|
||||
}
|
||||
|
||||
this._netNode.send(send_data,otherData,force);
|
||||
}
|
||||
|
||||
public close(code?: number, reason?: string):void {
|
||||
this._netNode.closeSocket(code, reason);
|
||||
}
|
||||
|
||||
public changeConnect(options: NetConnectOptions):void {
|
||||
this._netNode.changeConect(options);
|
||||
}
|
||||
public tryConnet():void{
|
||||
this._netNode.tryConnet();
|
||||
}
|
||||
}
|
||||
11
assets/scripts/network/socket/NetManager.ts.meta
Normal file
11
assets/scripts/network/socket/NetManager.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "939d67e2-2bd1-4d45-8009-a1a404324dfa",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
405
assets/scripts/network/socket/NetNode.ts
Normal file
405
assets/scripts/network/socket/NetNode.ts
Normal file
@@ -0,0 +1,405 @@
|
||||
|
||||
import { RequestObject, NetEvent } from "./NetInterface";
|
||||
import { NetTimer } from "./NetTimer";
|
||||
import { WebSock } from "./WebSock";
|
||||
import { EventMgr } from "../../utils/EventMgr";
|
||||
|
||||
|
||||
export enum NetTipsType {
|
||||
Connecting,
|
||||
ReConnecting,
|
||||
Requesting,
|
||||
}
|
||||
|
||||
export enum NetNodeState {
|
||||
Closed, // 已关闭
|
||||
Connecting, // 连接中
|
||||
Checking, // 验证中
|
||||
Working, // 可传输数据
|
||||
}
|
||||
|
||||
|
||||
export enum NetNodeType {
|
||||
BaseServer, //主要服务器
|
||||
ChatServer, //聊天服务器
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface NetConnectOptions {
|
||||
host?: string, // 地址
|
||||
port?: number, // 端口
|
||||
url?: string, // url,与地址+端口二选一
|
||||
autoReconnect?: number, // -1 永久重连,0不自动重连,其他正整数为自动重试次数
|
||||
type?:NetNodeType, //服务器类型
|
||||
}
|
||||
|
||||
export class NetNode {
|
||||
protected _connectOptions: NetConnectOptions = null;
|
||||
protected _autoReconnect: number = 0;
|
||||
protected _autoReconnectMax: number = 3;
|
||||
protected _state: NetNodeState = NetNodeState.Closed; // 节点当前状态
|
||||
protected _socket: WebSock = null; // Socket对象(可能是原生socket、websocket、wx.socket...)
|
||||
protected _timer:NetTimer = null;
|
||||
|
||||
|
||||
protected _keepAliveTimer: any = null; // 心跳定时器
|
||||
protected _reconnectTimer: any = null; // 重连定时器
|
||||
protected _heartTime: number = 10*1000; // 心跳间隔
|
||||
protected _receiveTime: number = 15*1000; // 多久没收到数据断开
|
||||
protected _reconnetTimeOut: number = 2*1000; // 重连间隔
|
||||
protected _requests: RequestObject[] = Array<RequestObject>(); // 请求列表
|
||||
protected _maxSeqId :number = 1000000;
|
||||
protected _seqId :number = 1;
|
||||
protected _invokePool:any = [];
|
||||
|
||||
/********************** 网络相关处理 *********************/
|
||||
public init() {
|
||||
console.log(`NetNode init socket`);
|
||||
this._socket = new WebSock();
|
||||
this.initSocket();
|
||||
this._timer = new NetTimer();
|
||||
this.initTimer();
|
||||
this._invokePool = [];
|
||||
|
||||
}
|
||||
|
||||
public connect(options: NetConnectOptions): boolean {
|
||||
console.log(`NetNode connect socket:`,options);
|
||||
if (this._socket && this._state == NetNodeState.Closed) {
|
||||
this._state = NetNodeState.Connecting;
|
||||
if (!this._socket.connect(options)) {
|
||||
this.updateNetTips(NetTipsType.Connecting, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._connectOptions == null) {
|
||||
options.autoReconnect = options.autoReconnect;
|
||||
}
|
||||
this._connectOptions = options;
|
||||
this.updateNetTips(NetTipsType.Connecting, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更换线路
|
||||
* @param options
|
||||
*/
|
||||
public changeConect(options: NetConnectOptions){
|
||||
if(options == this._connectOptions){
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._state != NetNodeState.Closed){
|
||||
this.closeSocket();
|
||||
}
|
||||
this.connect(options);
|
||||
}
|
||||
|
||||
protected initSocket() {
|
||||
this._autoReconnect = this._autoReconnectMax;
|
||||
this._socket.onConnected = (event) => { this.onConnected(event) };
|
||||
this._socket.onJsonMessage = (msg) => { this.onMessage(msg) };
|
||||
this._socket.onError = (event) => { this.onError(event) };
|
||||
this._socket.onClosed = (event) => { this.onClosed(event) };
|
||||
this._socket.onGetKey = () => { this.onGetKey() };
|
||||
|
||||
EventMgr.on(NetEvent.ServerHandShake, this.onChecked, this);
|
||||
}
|
||||
|
||||
|
||||
protected onGetKey(){
|
||||
this._state = NetNodeState.Working;
|
||||
|
||||
// if(this._connectOptions.type == NetNodeType.BaseServer){
|
||||
|
||||
// }else{
|
||||
// this.onChecked();
|
||||
// }
|
||||
|
||||
EventMgr.emit(NetEvent.ServerCheckLogin);
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected initTimer(){
|
||||
this._timer.init();
|
||||
|
||||
EventMgr.on(NetEvent.ServerTimeOut, this.onTimeOut, this);
|
||||
}
|
||||
|
||||
protected onTimeOut(msg:any){
|
||||
console.log("NetNode onTimeOut!",msg)
|
||||
//超时删除 请求队列
|
||||
for (var i = 0; i < this._requests.length;i++) {
|
||||
let req = this._requests[i];
|
||||
if(msg.name == req.rspName && msg.seq == req.seq){
|
||||
this._requests.splice(i, 1);
|
||||
this.destroyInvoke(req);
|
||||
i--;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected updateNetTips(tipsType: NetTipsType, isShow: boolean) {
|
||||
if (tipsType == NetTipsType.Requesting) {
|
||||
// EventMgr.emit(NetEvent.ServerRequesting, isShow);
|
||||
|
||||
} else if (tipsType == NetTipsType.Connecting) {
|
||||
|
||||
} else if (tipsType == NetTipsType.ReConnecting) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 网络连接成功
|
||||
protected onConnected(event) {
|
||||
console.log("NetNode onConnected!")
|
||||
this._autoReconnect = this._autoReconnectMax;
|
||||
|
||||
this.clearTimer();
|
||||
// 启动心跳
|
||||
this.resetHearbeatTimer();
|
||||
|
||||
// EventMgr.emit(NetEvent.ServerConnected);
|
||||
}
|
||||
|
||||
// 连接验证成功,进入工作状态
|
||||
protected onChecked() {
|
||||
console.log("NetNode onChecked!")
|
||||
|
||||
// 关闭连接或重连中的状态显示
|
||||
this.updateNetTips(NetTipsType.Connecting, false);
|
||||
this.updateNetTips(NetTipsType.ReConnecting, false);
|
||||
|
||||
if (this._requests.length > 0) {
|
||||
for (var i = 0; i < this._requests.length;i++) {
|
||||
let req = this._requests[i];
|
||||
if(req.sended == false){
|
||||
this.socketSend(req);
|
||||
}
|
||||
|
||||
}
|
||||
// 如果还有等待返回的请求,启动网络请求层
|
||||
}
|
||||
}
|
||||
|
||||
// 接收到一个完整的消息包
|
||||
protected onMessage(msg): void {
|
||||
// console.log(`NetNode onMessage msg ` ,msg);
|
||||
|
||||
if(msg){
|
||||
|
||||
// 接受到数据,重新定时收数据计时器
|
||||
//推送
|
||||
if(msg.seq == 0){
|
||||
EventMgr.emit(msg.name, msg);
|
||||
// console.log("all_push:",msg.name, msg);
|
||||
}else{
|
||||
this.cannelMsgTimer(msg);
|
||||
|
||||
// console.log("this._requests.length:",this._requests.length)
|
||||
for (var i = 0; i < this._requests.length;i++) {
|
||||
let req = this._requests[i];
|
||||
if(msg.name == req.rspName && msg.seq == req.seq && req.sended == true){
|
||||
this._requests.splice(i, 1);
|
||||
i--;
|
||||
// console.log("返回:",msg.name,"耗时:",new Date().getTime() - req.startTime)
|
||||
EventMgr.emit(msg.name, msg , req.otherData);
|
||||
this.destroyInvoke(req);
|
||||
EventMgr.emit(NetEvent.ServerRequestSucess,msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected onError(event) {
|
||||
console.log("onError:",event);
|
||||
|
||||
//出错后清空定时器 那后断开服务 尝试链接
|
||||
this.clearTimer();
|
||||
this.restReq();
|
||||
this.tryConnet();
|
||||
}
|
||||
|
||||
protected onClosed(event) {
|
||||
console.log("onClosed:",event);
|
||||
|
||||
//出错后
|
||||
this.clearTimer();
|
||||
this.tryConnet();
|
||||
}
|
||||
|
||||
protected restReq(){
|
||||
for (var i = 0; i < this._requests.length;i++) {
|
||||
let req = this._requests[i];
|
||||
req.sended = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重连
|
||||
*/
|
||||
public tryConnet(){
|
||||
console.log("tryConnet",this._autoReconnect)
|
||||
if (this.isAutoReconnect()) {
|
||||
this.updateNetTips(NetTipsType.ReConnecting, true);
|
||||
|
||||
|
||||
this._socket.close();
|
||||
this._state = NetNodeState.Closed;
|
||||
|
||||
this._reconnectTimer = setTimeout(() => {
|
||||
console.log("NetNode tryConnet!")
|
||||
this.connect(this._connectOptions);
|
||||
if (this._autoReconnect > 0) {
|
||||
this._autoReconnect -= 1;
|
||||
}
|
||||
|
||||
|
||||
}, this._reconnetTimeOut);
|
||||
} else {
|
||||
this._state = NetNodeState.Closed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 只是关闭Socket套接字(仍然重用缓存与当前状态)
|
||||
public closeSocket(code?: number, reason?: string) {
|
||||
this.clearTimer();
|
||||
this._requests.length = 0;
|
||||
this._seqId = 1;
|
||||
this._autoReconnect = 0;
|
||||
|
||||
if (this._socket) {
|
||||
this._socket.close(code, reason);
|
||||
} else {
|
||||
this._state = NetNodeState.Closed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public send(send_data:any,otherData:any,force: boolean = false):void{
|
||||
|
||||
var data = this.createInvoke();//new RequestObject();
|
||||
data.json = send_data;
|
||||
data.rspName = send_data.name;
|
||||
data.otherData = otherData;
|
||||
|
||||
this.sendPack(data,force);
|
||||
}
|
||||
|
||||
// 发起请求,如果当前处于重连中,进入缓存列表等待重连完成后发送
|
||||
public sendPack(obj: RequestObject, force: boolean = false): boolean {
|
||||
if (this._state == NetNodeState.Working || force) {
|
||||
this.socketSend(obj);
|
||||
this._requests.push(obj);
|
||||
}
|
||||
|
||||
else if (this._state == NetNodeState.Checking ||
|
||||
this._state == NetNodeState.Connecting) {
|
||||
this._requests.push(obj);
|
||||
}
|
||||
|
||||
else if(this._state == NetNodeState.Closed){
|
||||
this.connect(this._connectOptions);
|
||||
this._requests.push(obj);
|
||||
}
|
||||
|
||||
else {
|
||||
console.error("NetNode request error! current state is " + this._state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 打包发送
|
||||
* @param obj
|
||||
*/
|
||||
public socketSend(obj:RequestObject){
|
||||
obj.seq = obj.json.seq = this._seqId;
|
||||
obj.startTime = new Date().getTime()
|
||||
this._socket.packAndSend(obj.json);
|
||||
this._seqId+=1;
|
||||
obj.sended = true;
|
||||
this._timer.schedule(obj.json,this._receiveTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 心跳
|
||||
*/
|
||||
public getHearbeat(){
|
||||
var obj = this.createInvoke();//new RequestObject();
|
||||
obj.json = {name:"heartbeat",msg:{ctime:new Date().getTime()},seq:0};
|
||||
obj.rspName = "heartbeat";
|
||||
obj.seq = 0;
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/********************** 心跳、超时相关处理 *********************/
|
||||
protected cannelMsgTimer(data:any = null) {
|
||||
this._timer.cancel(data);
|
||||
}
|
||||
|
||||
protected resetHearbeatTimer() {
|
||||
if (this._keepAliveTimer !== null) {
|
||||
clearInterval(this._keepAliveTimer);
|
||||
}
|
||||
|
||||
this._keepAliveTimer = setInterval(() => {
|
||||
this.sendPack(this.getHearbeat());
|
||||
}, this._heartTime);
|
||||
}
|
||||
|
||||
protected clearTimer() {
|
||||
if (this._keepAliveTimer !== null) {
|
||||
clearTimeout(this._keepAliveTimer);
|
||||
}
|
||||
if (this._reconnectTimer !== null) {
|
||||
clearTimeout(this._reconnectTimer);
|
||||
}
|
||||
this._timer.destroy();
|
||||
}
|
||||
|
||||
public isAutoReconnect() {
|
||||
return this._autoReconnect != 0;
|
||||
}
|
||||
|
||||
public rejectReconnect() {
|
||||
this._autoReconnect = 0;
|
||||
this.clearTimer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected createInvoke():RequestObject{
|
||||
// console.log("createInvoke_invokePool :",this._invokePool.length)
|
||||
if (this._invokePool.length > 0) {
|
||||
return this._invokePool.shift();
|
||||
}
|
||||
return new RequestObject();
|
||||
}
|
||||
|
||||
protected destroyInvoke(invoke:RequestObject):void {
|
||||
invoke.destroy();
|
||||
this._invokePool.push(invoke);
|
||||
// console.log("destroyInvoke_invokePool :",this._invokePool.length)
|
||||
}
|
||||
}
|
||||
11
assets/scripts/network/socket/NetNode.ts.meta
Normal file
11
assets/scripts/network/socket/NetNode.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2347520e-e635-4077-82bf-f16e1d41505a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
88
assets/scripts/network/socket/NetTimer.ts
Normal file
88
assets/scripts/network/socket/NetTimer.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
import { _decorator } from 'cc';
|
||||
import { NetEvent } from "./NetInterface";
|
||||
import { EventMgr } from '../../utils/EventMgr';
|
||||
|
||||
|
||||
export class NetTimerData {
|
||||
public name:string = "";
|
||||
public seq:number = 0;
|
||||
public timeId:number = 0;
|
||||
}
|
||||
|
||||
export class NetTimer {
|
||||
private _tokens:any = null;
|
||||
private _tokenId:number = 0;
|
||||
public init(){
|
||||
this._tokens = new Map();
|
||||
this._tokenId = 0;
|
||||
}
|
||||
|
||||
public schedule(data:any,delay:number = 0):void{
|
||||
|
||||
var self = this;
|
||||
var token = this._tokenId++;
|
||||
var id = setTimeout(function() { self.handleTimeout(token); }, delay);
|
||||
|
||||
var timerData = new NetTimerData();
|
||||
timerData.name = data.name;
|
||||
timerData.seq = data.seq;
|
||||
timerData.timeId = id;
|
||||
|
||||
// console.log("NetTimer token size:",this._tokens.size,token)
|
||||
this._tokens.set(token,timerData);
|
||||
}
|
||||
|
||||
|
||||
private handleTimeout(id:number = 0):void{
|
||||
var data = this._tokens.get(id);
|
||||
if(data){
|
||||
EventMgr.emit(NetEvent.ServerTimeOut, data);
|
||||
this._tokens.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public cancel(data:any):void{
|
||||
if(data == null){
|
||||
return
|
||||
}
|
||||
var id = -1;
|
||||
if(typeof(data)=='object'){
|
||||
id = this.getKey(data);
|
||||
}else{
|
||||
id = data;
|
||||
}
|
||||
|
||||
// console.log("NetTimer token id:",id)
|
||||
if(id >= 0){
|
||||
this._tokens.delete(id);
|
||||
clearTimeout(id);
|
||||
// console.log("NetTimer token cancel:",this._tokens.size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private getKey(data:any):number{
|
||||
var return_key = -1;
|
||||
this._tokens.forEach((value , key) =>{
|
||||
if(value.name == data.name && value.seq == data.seq){
|
||||
return_key = key;
|
||||
}
|
||||
});
|
||||
|
||||
return return_key;
|
||||
}
|
||||
|
||||
|
||||
public destroy():void{
|
||||
var self = this;
|
||||
this._tokens.forEach(function(key, value){
|
||||
self.cancel(key);
|
||||
});
|
||||
this._tokens.clear();
|
||||
}
|
||||
|
||||
}
|
||||
11
assets/scripts/network/socket/NetTimer.ts.meta
Normal file
11
assets/scripts/network/socket/NetTimer.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ac6aa200-3f4b-408d-a5a5-86759a7df57d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
198
assets/scripts/network/socket/WebSock.ts
Normal file
198
assets/scripts/network/socket/WebSock.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
import { ISocket } from "./NetInterface";
|
||||
import * as crypto from "../../libs/crypto/crypto"
|
||||
import * as gzip from "../../libs/gzip/gzip";
|
||||
import { convert } from "../../libs/convert";
|
||||
|
||||
|
||||
|
||||
export class WebSock implements ISocket {
|
||||
private _ws: WebSocket = null; // websocket对象
|
||||
private _key:String = "";
|
||||
|
||||
|
||||
onConnected(event):void{
|
||||
console.log("websocket onConnected:",event);
|
||||
}
|
||||
|
||||
|
||||
onJsonMessage(data:any){
|
||||
|
||||
}
|
||||
|
||||
|
||||
onGetKey(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
onMessage(msg):void{
|
||||
|
||||
// console.log("websocket onMessage0:",msg)
|
||||
var ab = msg
|
||||
var view = new Uint8Array(ab)
|
||||
var undata = gzip.unzip(view)
|
||||
var c = new convert()
|
||||
msg = c.byteToString(undata)
|
||||
// console.log("websocket onMessage1:",msg)
|
||||
|
||||
//第一次
|
||||
if(this._key == ""){
|
||||
try {
|
||||
var hand_data = JSON.parse(msg);
|
||||
console.log("hand_data:",hand_data)
|
||||
if(hand_data.name == "handshake"){
|
||||
this._key = hand_data.msg.key;
|
||||
this.onGetKey();
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("handshake parse error:",error)
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("websocket onMessage2:",msg)
|
||||
|
||||
var decrypted = null;
|
||||
try {
|
||||
decrypted = this.getAnddecrypt(msg);
|
||||
} catch (error) {
|
||||
console.log("message ecrypt error:",error)
|
||||
}
|
||||
|
||||
if(decrypted == ""){
|
||||
this._key = "";
|
||||
}
|
||||
// console.log("onMessage decrypted :",decrypted);
|
||||
if(decrypted){
|
||||
var json = JSON.parse(decrypted);
|
||||
this.onJsonMessage(json);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
onError(event):void{
|
||||
console.log("websocket onError:",event)
|
||||
}
|
||||
|
||||
onClosed(event):void{
|
||||
console.log("websocket onClosed:",event)
|
||||
}
|
||||
|
||||
connect(options: any) {
|
||||
if (this._ws) {
|
||||
if (this._ws.readyState === WebSocket.CONNECTING) {
|
||||
console.log("websocket connecting, wait for a moment...")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let url = null;
|
||||
if(options.url) {
|
||||
url = options.url;
|
||||
} else {
|
||||
let ip = options.ip;
|
||||
let port = options.port;
|
||||
let protocol = options.protocol;
|
||||
url = `${protocol}://${ip}:${port}`;
|
||||
}
|
||||
console.log()
|
||||
this._ws = new WebSocket(url);
|
||||
this._ws.binaryType = options.binaryType ? options.binaryType : "arraybuffer";
|
||||
this._ws.onmessage = (event) => {
|
||||
this.onMessage(event.data);
|
||||
};
|
||||
|
||||
this._ws.onopen = this.onConnected;
|
||||
this._ws.onerror = this.onError;
|
||||
this._ws.onclose = this.onClosed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
send(buffer: any) {
|
||||
if (this._ws.readyState == WebSocket.OPEN)
|
||||
{
|
||||
this._ws.send(buffer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
close(code?: number, reason?: string) {
|
||||
this._key = "";
|
||||
this._ws.close(code, reason);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* json 加密打包
|
||||
* @param send_data
|
||||
*/
|
||||
public packAndSend(send_data:any){
|
||||
//console.log("WebSocke packAndSend:",send_data)
|
||||
var encrypt = this._key == ""?send_data:this.encrypt(send_data);
|
||||
//console.log("encrypt:",encrypt);
|
||||
|
||||
var data = gzip.zip(encrypt, {level:9});
|
||||
var c = new convert()
|
||||
var undata = gzip.unzip(data)
|
||||
//var msg = c.byteToString(undata)
|
||||
//console.log("unzip:", msg);
|
||||
|
||||
var buffer = new ArrayBuffer(data.length);
|
||||
var i8arr = new Int8Array(buffer);
|
||||
for(var i = 0; i < i8arr.length; i++){
|
||||
i8arr[i]= data[i];
|
||||
}
|
||||
|
||||
// console.log("i8arr:",i8arr)
|
||||
this.send(i8arr)
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param msg
|
||||
*/
|
||||
public getAnddecrypt(get_msg:any){
|
||||
var decrypt = this._key == ""?get_msg:this.decrypt(get_msg);
|
||||
// console.log("decrypt:",decrypt);
|
||||
return decrypt
|
||||
}
|
||||
|
||||
|
||||
encrypt(data:any) {
|
||||
var key = crypto.enc.Utf8.parse(this._key);
|
||||
var iv = crypto.enc.Utf8.parse(this._key);
|
||||
|
||||
if(typeof(data)=='object'){
|
||||
data = JSON.stringify(data);
|
||||
}
|
||||
let srcs = crypto.enc.Utf8.parse(data);
|
||||
let encrypted = crypto.AES.encrypt(srcs, key, { iv: iv, mode: crypto.mode.CBC, padding: crypto.pad.ZeroPadding });
|
||||
|
||||
|
||||
return encrypted.ciphertext.toString()
|
||||
}
|
||||
|
||||
|
||||
decrypt(message:string) {
|
||||
var key = crypto.enc.Utf8.parse(this._key);
|
||||
var iv = crypto.enc.Utf8.parse(this._key);
|
||||
|
||||
let encryptedHexStr = crypto.enc.Hex.parse(message);
|
||||
let srcs = crypto.Base64.stringify(encryptedHexStr);
|
||||
let decrypt = crypto.AES.decrypt(srcs, key, { iv: iv, mode: crypto.mode.CBC, padding: crypto.pad.ZeroPadding });
|
||||
// console.log("decrypt:", decrypt);
|
||||
|
||||
let decryptedStr = decrypt.toString(crypto.enc.Utf8);
|
||||
// console.log("decryptedStr 1111:", typeof(decryptedStr), decryptedStr, decryptedStr.length);
|
||||
var str = decryptedStr.replaceAll("\u0000", "")
|
||||
|
||||
// console.log("decryptedStr 2222:", typeof(str), str, str.length);
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
11
assets/scripts/network/socket/WebSock.ts.meta
Normal file
11
assets/scripts/network/socket/WebSock.ts.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "bd622a27-7676-4b74-bf36-1a4c3eb61cbb",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user