135 lines
3.8 KiB
TypeScript
135 lines
3.8 KiB
TypeScript
export interface IConnection{
|
||
endpoint: string;
|
||
autoReconnect?: boolean | {
|
||
timeout: number;
|
||
}
|
||
}
|
||
|
||
const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
|
||
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(options: IConnection){
|
||
|
||
if(options.endpoint == "auto")
|
||
{
|
||
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)
|
||
}
|
||
}
|
||
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));
|
||
}
|
||
}
|
||
} |