@xmobitea/gn-typescript-client
Version:
GearN Typescript Client SDK by XmobiTea (Pro)
162 lines (161 loc) • 7.46 kB
JavaScript
import { GNHashtable } from "./../common/GNData";
import { ParameterCode } from "./../constant/parameterCode/ParameterCode";
import { ReturnCode } from "./../constant/ReturnCode";
import { OperationResponse } from "./../entity/OperationResponse";
import { GNNetwork } from "./../GNNetwork";
import { GNDebug } from "./../logger/GNDebug";
import { OperationPending } from "./OperationPending";
import store from "store";
export class PeerBase {
constructor() {
this.perMsgTimer = 0;
this.nextSendMsgTimer = 0;
this.checkTimeoutOperationPending = 0;
}
getSendRate() {
return (1000 / this.perMsgTimer);
}
setSendRate(sendRate) {
this.perMsgTimer = 1000 / sendRate / 1000;
}
initPeer() {
if (this.operationWaitingResponseDict == null)
this.operationWaitingResponseDict = new Map();
if (this.operationPendingQueue == null)
this.operationPendingQueue = [];
if (this.pingLst == null)
this.pingLst = [];
this.initSendRate();
this.initGNSocketObject();
}
initSendRate() {
let gnServerSettings = GNNetwork.getGNServerSettings();
if (gnServerSettings == null)
throw new Error("Null GN Server Settings, please find it now");
this.setSendRate(gnServerSettings.getSendRate());
}
enqueue(requestType, role, operationRequest, onOperationResponse, authToken, secretKey, customTags, gameId) {
if (!this.isUsing) {
GNDebug.logError("[GearN] Server Settings dont setup to use this to send operation request.");
return;
}
if (operationRequest.getRequestId() != -1)
operationRequest.setRequestId(++PeerBase.requestId);
let operationPending = new OperationPending(requestType, role, operationRequest, onOperationResponse, authToken, secretKey, customTags, gameId);
this.operationPendingQueue.push(operationPending);
this.onEnqueue(operationPending);
}
isUsing() {
return this.isUse;
}
service() {
if (!this.isUsing)
return;
let nowSecond = Date.now() / 1000;
if (this.checkTimeoutOperationPending < nowSecond) {
this.checkTimeoutOperationPending = nowSecond + 0.1;
if (this.operationWaitingResponseDict.size != 0) {
let gnHashtableLst = [];
this.operationWaitingResponseDict.forEach((operationPending, operationPendingKey) => {
if (operationPending.isTimeout()) {
let gnHashtable = new GNHashtable();
gnHashtable.add(ParameterCode.ReturnCode, ReturnCode.OperationTimeout);
gnHashtable.add(ParameterCode.Parameters, null);
gnHashtable.add(ParameterCode.ResponseId, operationPending.getOperationRequest().getRequestId());
gnHashtableLst.push(gnHashtable);
}
});
if (gnHashtableLst.length != 0) {
gnHashtableLst.forEach(gnHashtable => {
this.onResponseHandler(gnHashtable);
});
}
}
}
if (this.nextSendMsgTimer < nowSecond) {
if (this.operationPendingQueue.length != 0) {
this.nextSendMsgTimer = nowSecond + this.perMsgTimer;
let operationPending = this.operationPendingQueue.shift();
this.send(operationPending);
}
}
}
onResponseHandler(obj) {
let responseId = obj.getNumber(ParameterCode.ResponseId);
if (this.operationWaitingResponseDict.has(responseId)) {
let operationPending = this.operationWaitingResponseDict.get(responseId);
operationPending.onRecv();
this.operationWaitingResponseDict.delete(responseId);
let returnCode = obj.getNumber(ParameterCode.ReturnCode);
let parameters = obj.getGNHashtable(ParameterCode.Parameters);
let debugMessage = obj.getString(ParameterCode.DebugMessage);
let invalidRequestParameterArray = obj.getGNArray(ParameterCode.InvalidRequestParameters);
let operationRequest = operationPending.getOperationRequest();
let operationResponse = new OperationResponse(operationRequest.getOperationCode(), operationRequest.getRequestId());
operationResponse.setReturnCode(returnCode);
operationResponse.setDebugMessage(debugMessage);
operationResponse.setParameters(parameters);
if (invalidRequestParameterArray != null) {
let invalidMembers = [];
for (let i = 0; i < invalidRequestParameterArray.count(); i++) {
let arrChild = invalidRequestParameterArray.getGNArray(i);
invalidMembers.push({
code: arrChild.getString(0),
invalidMemberType: arrChild.getNumber(1)
});
}
operationResponse.setInvalidMembers(invalidMembers);
}
if (!operationResponse.hasError()) {
this.addPing(operationPending.getExecuteTimerInMs());
if (parameters != null) {
if (parameters.containsKey(ParameterCode.AuthToken)) {
let authToken = parameters.getString(ParameterCode.AuthToken);
GNNetwork.getAuthenticateStatus().setAuthToken(authToken);
store.set(GNNetwork.AUTH_TOKEN_KEY, authToken);
}
if (parameters.containsKey(ParameterCode.UserId)) {
let userId = parameters.getString(ParameterCode.UserId);
GNNetwork.getAuthenticateStatus().setUserId(userId);
store.set(GNNetwork.USER_ID_KEY, userId);
}
if (parameters.containsKey(ParameterCode.Ts)) {
GNNetwork.peer.setServerTimeMilliseconds(parameters.getNumber(ParameterCode.Ts, new Date().getUTCMilliseconds()));
}
}
}
GNDebug.log("[GN RECV] " + operationResponse.toString());
let callback = operationPending.getCallback();
if (callback != null)
callback(operationResponse);
}
else {
GNDebug.logError("[GearN] OnResponseHandler, unavailable request id " + obj);
}
}
send(operationPending) {
operationPending.onSend();
let operationRequest = operationPending.getOperationRequest();
if (operationRequest.getRequestId() != -1) {
if (operationPending.getCallback() != null) {
this.operationWaitingResponseDict.set(operationRequest.getRequestId(), operationPending);
}
}
}
addPing(value) {
if (this.pingLst.length > 10)
this.pingLst.shift();
this.pingLst.push(value / 2);
if (this.pingLst.length != 0) {
let total = 0;
for (let i = 0; i < this.pingLst.length; i++) {
total += this.pingLst[i];
}
let average = total / this.pingLst.length;
this.ping = (average * 1000);
}
else
this.ping = -1;
}
}
PeerBase.requestId = 0;