export function documentNameToURL(documentName: string): string {
const location = document.location;
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
return `${protocol}//${location.host}/documents/${documentName}`;
}
export class WebSocketManager {
private currentUrl: string = "";
private sock?: WebSocket;
onopen: (url: string, socket: WebSocket) => void = (url, sock) => { };
onclose: (url: string) => void = (url) => { };
ondata: (url: string, socket: WebSocket, msg: MessageEvent) => void = (url, sock, msg) => { };
connect = (url: string): boolean => {
if (url === this.currentUrl) {
return false;
}
this.close();
this.currentUrl = url;
this.reconnect(url);
return true;
}
close = (): void => {
this.sock?.close();
this.sock = undefined;
}
reconnect = (url: string): void => {
if (url !== this.currentUrl) {
return;
}
const sock = new WebSocket(url);
this.sock = sock;
sock.onopen = (event: Event) => {
if (sock !== this.sock) {
sock.close();
return;
}
this.onopen(url, sock);
};
sock.onclose = (event: Event) => {
if (sock !== this.sock) {
return;
}
this.sock = undefined;
this.onclose(url);
setTimeout(() => {
if (this.sock !== undefined) {
return;
}
this.reconnect(url);
}, 1000);
};
sock.onmessage = (event: MessageEvent) => {
if (sock !== this.sock) {
sock.close();
return;
}
this.ondata(url, sock, event);
};
}
send = (msg: ArrayBufferView): void => {
const sock = this.sock;
if (sock && sock.readyState === WebSocket.OPEN) {
sock.send(msg);
}
}
}