UNPKG

mydog

Version:

a framework of typescript game server

272 lines (236 loc) 9.67 kB
/** * app class */ import * as path from "path" import { I_someConfig, I_clientSocket, I_connectorConfig, I_encodeDecodeConfig, I_rpcConfig, ServerInfo, loggerLevel } from "./util/interfaceDefine"; import * as appUtil from "./util/appUtil"; import { EventEmitter } from "events"; import { RpcSocketPool } from "./components/rpcSocketPool"; import { FrontendServer } from "./components/frontendServer"; import { BackendServer } from "./components/backendServer"; import { Session } from "./components/session"; import { Filter, I_before, I_after, I_globalBefore } from "./components/filter"; declare global { interface Rpc { } } export default class Application extends EventEmitter { appName: string = "hello world"; // App name hasStarted: boolean = false; // Whether has started main: string = ""; // Startup file base: string = path.dirname((require.main as any).filename); // Root path routeConfig: string[] = []; // route.ts masterConfig: ServerInfo = {} as ServerInfo; // master.ts serversConfig: { [serverType: string]: ServerInfo[] } = {}; // servers.ts routeConfig2: string[][] = []; // route.ts (split) clientNum: number = 0; // Number of all socket connections clients: { [uid: number]: I_clientSocket } = {}; // Sockets that have been binded settings: { [key: string]: any } = {}; // User set,get servers: { [serverType: string]: ServerInfo[] } = {}; // All user servers that are running serversIdMap: { [id: string]: ServerInfo } = {}; // All user servers that are running (Dictionary format) serverInfo: ServerInfo = {} as ServerInfo; // The configuration of this server isDaemon: boolean = false; // Whether to run in the background env: string = ""; // environment serverId: string = ""; // Server name id, the unique identifier of the server serverType: string = ""; // Server type frontend: boolean = false; // Is it a front-end server startMode: "all" | "alone" = "all"; // Start Mode: all / alone startTime: number = 0; // Start time router: { [serverType: string]: (session: Session, cmd: number) => string } = {}; // Pre-selection when routing messages to the backend rpc: (serverId: string) => Rpc = null as any; // Rpc packaging rpcPool: RpcSocketPool = new RpcSocketPool(); // Rpc socket pool logger: (level: loggerLevel, err: Error | string) => void = function () { }; // Internal msg log output msgEncode: Required<I_encodeDecodeConfig>["msgEncode"] = null as any; msgDecode: Required<I_encodeDecodeConfig>["msgDecode"] = null as any; protoEncode: Required<I_encodeDecodeConfig>["protoEncode"] = null as any; protoDecode: Required<I_encodeDecodeConfig>["protoDecode"] = null as any; someconfig: I_someConfig = {} as any; // Partially open configuration noRpcMatrix: { [svrT_svrT: string]: boolean } = {}; // The configuration of not establishing a socket connection between servers frontendServer: FrontendServer = null as any; backendServer: BackendServer = null as any; filter = new Filter(); constructor() { super(); appUtil.defaultConfiguration(this); } /** * Start up */ start() { if (this.hasStarted) { console.error("the app has already started"); return; } this.hasStarted = true; this.startTime = new Date().getTime(); appUtil.startServer(this); } setConfig(key: keyof I_someConfig, value: any): void { this.someconfig[key] = value; if (key === "logger") { this.logger = value; } else if (key === "rpc") { let noRpcMatrix = value["noRpcMatrix"] || {}; for (let svrT1 in noRpcMatrix) { let arr = noRpcMatrix[svrT1]; for (let svrT2 of arr) { this.noRpcMatrix[appUtil.getNoRpcKey(svrT1, svrT2)] = true; } } } } /** * Set key-value pairs */ set(key: string | number, value: any) { this.settings[key] = value; return value; } /** * Get the value corresponding to the key */ get(key: string | number) { return this.settings[key]; } /** * Delete a key-value pair */ delete(key: string | number) { delete this.settings[key]; } /** * Get the server array according to the server type */ getServersByType(serverType: string) { return this.servers[serverType] || []; } /** * Get a server configuration */ getServerById(serverId: string) { return this.serversIdMap[serverId]; } /** * Routing configuration (deciding which backend to call) * @param serverType Back-end server type * @param routeFunc Configuration function */ route(serverType: string, routeFunc: (session: Session, cmd: number) => string) { this.router[serverType] = routeFunc; } /** * get session by uid */ getSession(uid: number) { let client = this.clients[uid]; if (client) { return client.session; } else { return null; } } /** * get all clients */ getAllClients() { return this.clients; } /** * Send a message to the client * @param cmd cmd * @param msg message * @param uids uid array [1,2] */ sendMsgByUid(cmd: number, msg: any, uids: number[]) { if (msg === undefined) { msg = null; } let msgBuf = this.protoEncode(cmd, msg); let client: I_clientSocket; let i: number; for (i = 0; i < uids.length; i++) { client = this.clients[uids[i]]; if (client) { client.send(msgBuf); } } } /** * Send messages to all clients * @param cmd cmd * @param msg message */ sendAll(cmd: number, msg: any) { if (msg === undefined) { msg = null; } let data = this.protoEncode(cmd, msg); let uid: string; for (uid in this.clients) { this.clients[uid].send(data) } } /** * Send a message to the client * @param cmd cmd * @param msg message * @param uidsid uidsid array */ sendMsgByUidSid(cmd: number, msg: any, uidsid: { "uid": number, "sid": string }[]) { if (msg === undefined) { msg = null; } this.backendServer.sendMsgByUidSid(cmd, msg, uidsid); } /** * Send a message to the client * @param cmd cmd * @param msg message * @param group { sid : uid[] } */ sendMsgByGroup(cmd: number, msg: any, group: { [sid: string]: number[] }) { if (msg === undefined) { msg = null; } this.backendServer.sendMsgByGroup(cmd, msg, group); } /** * Configure server execution function * @param type Server type: "all" or "gate|connector" like * @param cb Execution function */ configure(type: string, cb: Function) { if (type === "all") { cb.call(this); return; } let ts = type.split("|"); for (let i = 0; i < ts.length; i++) { if (this.serverType === ts[i].trim()) { cb.call(this); break; } } } /** * Some front work before message processing * @param filter */ before(filter: { "before": I_before }) { this.filter.before(filter); } /** * Some post work after message processing * @param filter */ after(filter: { "after": I_after }) { this.filter.after(filter); } /** * Some processing of the message when it first reaches the gateway server * @param filter */ globalBefore(filter: { "before": I_globalBefore }) { this.filter.globalBefore(filter); } }