136 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
import MWSE from "frontend";
 | 
						||
 | 
						||
export interface IConnection{
 | 
						||
    endpoint: string;
 | 
						||
    autoReconnect?: boolean | {
 | 
						||
        timeout: number;
 | 
						||
    }
 | 
						||
}
 | 
						||
export class Connection
 | 
						||
{
 | 
						||
    public ws! : WebSocket;
 | 
						||
    public endpoint : URL;
 | 
						||
    public autoPair : boolean = false;
 | 
						||
    public connected : boolean = false;
 | 
						||
 | 
						||
    public autoReconnect : boolean = true;
 | 
						||
    public autoReconnectTimeout : number = 3000;
 | 
						||
    public autoReconnectTimer? : number;
 | 
						||
    constructor(mwse:MWSE, options: IConnection){
 | 
						||
 | 
						||
        if(options.endpoint == "auto")
 | 
						||
        {
 | 
						||
            const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
 | 
						||
            let scriptPath = new URL(RootURL);
 | 
						||
            let isSecurity  = scriptPath.protocol == "https:";
 | 
						||
            let dumeUrl = scriptPath.pathname.split('/').slice(0,-1).join('/') + '/';
 | 
						||
            let wsSocket = new URL(dumeUrl, scriptPath);
 | 
						||
            wsSocket.protocol = isSecurity ? 'wss:' : 'ws:';
 | 
						||
            this.endpoint = new URL(wsSocket.href);
 | 
						||
        }else{
 | 
						||
            try{
 | 
						||
                // Testing
 | 
						||
                this.endpoint = new URL(options.endpoint);
 | 
						||
            }catch{
 | 
						||
                throw new Error("endpoint is required")
 | 
						||
            }
 | 
						||
        }
 | 
						||
        if(typeof options.autoReconnect == "boolean")
 | 
						||
        {
 | 
						||
            this.autoReconnect = true;
 | 
						||
        }else if(options.autoReconnect)
 | 
						||
        {
 | 
						||
            this.autoReconnect = true;
 | 
						||
            this.autoReconnectTimeout = options.autoReconnect.timeout;
 | 
						||
        }
 | 
						||
    }
 | 
						||
    public connect()
 | 
						||
    {
 | 
						||
        if(this.autoReconnectTimer)
 | 
						||
        {
 | 
						||
            clearTimeout(this.autoReconnectTimer)
 | 
						||
        };
 | 
						||
        this.ws = new WebSocket(this.endpoint.href);
 | 
						||
        this.addWSEvents();
 | 
						||
    }
 | 
						||
    public disconnect()
 | 
						||
    {
 | 
						||
        /**
 | 
						||
         * Eğer bilinerek elle kapatıldıysa otomatik tekrar bağlanmasının
 | 
						||
         * önüne geçmek için autoReconnect bayrağını her zaman kapalı tutmak gerekir
 | 
						||
         */
 | 
						||
        this.autoReconnect = false;
 | 
						||
        this.ws.close();
 | 
						||
    }
 | 
						||
    public addWSEvents()
 | 
						||
    {
 | 
						||
        this.ws.addEventListener("open", () => this.eventOpen());
 | 
						||
        this.ws.addEventListener("close", () => this.eventClose());
 | 
						||
        this.ws.addEventListener("error", () => this.eventError());
 | 
						||
        this.ws.addEventListener("message", ({data}) => this.eventMessage(data as string | ArrayBuffer));
 | 
						||
    }
 | 
						||
    private eventOpen()
 | 
						||
    {
 | 
						||
        this.connected = true;
 | 
						||
        for (const callback of this.activeConnectionEvent) {
 | 
						||
            callback(void 0);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    private eventClose()
 | 
						||
    {
 | 
						||
        for (const callback of this.passiveConnectionEvent) {
 | 
						||
            callback(void 0);
 | 
						||
        }
 | 
						||
        this.connected = false;
 | 
						||
        if(this.autoReconnect)
 | 
						||
        {
 | 
						||
            this.autoReconnectTimer = setTimeout(() => this.connect(), this.autoReconnectTimeout) as unknown as number;
 | 
						||
        }
 | 
						||
    }
 | 
						||
    private eventError()
 | 
						||
    {
 | 
						||
        this.connected = false;
 | 
						||
    }
 | 
						||
    private recaivePackEvent : ((data:any) => any)[] = [];
 | 
						||
    public onRecaivePack(func:(data:any) => any)
 | 
						||
    {
 | 
						||
        this.recaivePackEvent.push(func);
 | 
						||
    }
 | 
						||
    private activeConnectionEvent : Function[] = [];
 | 
						||
    public onActive(func:Function)
 | 
						||
    {
 | 
						||
        if(this.connected)
 | 
						||
        {
 | 
						||
            func()
 | 
						||
        }else{
 | 
						||
            this.activeConnectionEvent.push(func);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    private passiveConnectionEvent : Function[] = [];
 | 
						||
    public onPassive(func:Function)
 | 
						||
    {
 | 
						||
        if(!this.connected)
 | 
						||
        {
 | 
						||
            func()
 | 
						||
        }else{
 | 
						||
            this.passiveConnectionEvent.push(func);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    private eventMessage(data: string | ArrayBuffer)
 | 
						||
    {
 | 
						||
        if(typeof data == "string")
 | 
						||
        {
 | 
						||
            let $data = JSON.parse(data);
 | 
						||
            for (const callback of this.recaivePackEvent) {
 | 
						||
                callback($data);
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
    public tranferToServer(data:any)
 | 
						||
    {
 | 
						||
        if(this.connected)
 | 
						||
        {
 | 
						||
            this.ws.send(JSON.stringify(data));
 | 
						||
        }
 | 
						||
    }
 | 
						||
} |