| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- export class JCEngine {
- public static entityClass: new() => JCEntity;
- public static boot(url: string, entityClass: new() => JCEntity) {
- JCEngine.entityClass = entityClass;
- new WebSocketServer(url);
- }
- }
- export class JCEntity {
- public id: number;
- public channel: JCChannel;
- public isValid: boolean;
- public onLoad() {}
- public onDestroy() {}
- public call(func: string, args?: any[], callback?: Function) {
- if (this.isValid) {
- let uuid = "";
- let type = JCDataType.FUNCTION;
- if (func.indexOf(".") > -1) {
- uuid = JCUtil.uuid();
- type = JCDataType.METHOD;
- if (!callback) {
- callback = arguments[arguments.length - 1];
- }
- CallbackManager.addCallback(uuid, callback);
- }
- if (args == undefined) {
- args = [];
- }
- let data = {uuid: uuid, type: type, func: func, args: args};
- this.channel.writeAndFlush(JSON.stringify(data));
- }
- }
- }
- class JCChannel {
- private webSocket: WebSocket;
- constructor(webSocket: WebSocket) {
- this.webSocket = webSocket;
- }
- public writeAndFlush(text: string) {
- this.webSocket.send(text);
- }
- public close() {
- this.webSocket.close();
- }
- }
- class WebSocketServer {
- private webSocket: WebSocket;
- private tempEntity: JCEntity;
- constructor(url: string) {
- if (this.webSocket && this.webSocket.OPEN) {
- this.webSocket.close();
- }
- this.webSocket = new WebSocket(url);
- this.webSocket.onopen = () => {
- this.call("loadTempEntity");
- }
- this.webSocket.onclose = () => {
- this.destroyTempEntity();
- }
- this.webSocket.onmessage = (event: MessageEvent) => {
- this.invoke(JSON.parse(event.data));
- }
- }
- private call(func: string, args?: any[]) {
- if (args == undefined) {
- args = [];
- }
- let data:JCData = {uuid: "", type: JCDataType.EVENT, func: func, args: args};
- this.webSocket.send(JSON.stringify(data));
- }
- private invoke(data: JCData) {
- if (data.type == JCDataType.EVENT) {
- this[data.func].apply(this, data.args);
- return;
- }
- if (data.type == JCDataType.FUNCTION) {
- if (this.tempEntity.isValid) {
- this.tempEntity[data.func].apply(this.tempEntity, data.args);
- }
- return;
- }
- if (data.type == JCDataType.METHOD) {
- CallbackManager.handleCallback(data);
- }
- }
- public loadTempEntity(id: number) {
- this.tempEntity = new JCEngine.entityClass();
- this.tempEntity.id = id;
- this.tempEntity.channel = new JCChannel(this.webSocket);
- this.tempEntity.isValid = true;
- this.tempEntity.onLoad();
- }
- public destroyTempEntity() {
- this.tempEntity.isValid = false;
- this.tempEntity.onDestroy();
- }
- }
- class CallbackManager {
- private static mapper: Map<string, CallbackInfo> = new Map();
- public static addCallback(uuid: string, callback: Function) {
- if (callback instanceof Function) {
- this.mapper.set(uuid, {
- callback: callback,
- deadTime: Date.now() + 10 * 1000
- });
- }
- }
- public static handleCallback(data: JCData) {
- if (this.mapper.size > 10) {
- let now = Date.now();
- for (let item of (this.mapper as any)) {
- let key = item[0].deadTime;
- let value = item[1];
- if (now >= value.deadTime) {
- this.mapper.delete(key);
- }
- }
- }
- let callbackInfo = this.mapper.get(data.uuid);
- if (callbackInfo && callbackInfo.callback instanceof Function) {
- this.mapper.delete(data.uuid);
- callbackInfo.callback(data.args[0]);
- }
- }
- }
- class JCUtil {
- public static uuid(): string {
- let arr = [];
- let hexDigits = "0123456789abcdef";
- for (let i = 0; i < 36; i++) {
- arr[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
- }
- arr[14] = "4";
- arr[19] = hexDigits.substr((arr[19] & 0x3) | 0x8, 1);
- arr[8] = arr[13] = arr[18] = arr[23] = "";
- return arr.join("");
- }
- }
- interface CallbackInfo {
- callback: Function;
- deadTime: number;
- }
- interface JCData {
- uuid: string;
- type: number;
- func: string;
- args: any[];
- }
- enum JCDataType {
- EVENT,
- FUNCTION,
- METHOD
- }
|