Files
scrypted/server/src/plugin/plugin-remote-websocket.ts
2021-09-08 13:19:51 -07:00

160 lines
3.9 KiB
TypeScript

interface WebSocketEvent {
type: string;
reason?: string;
message?: string;
data?: string|ArrayBufferLike;
source?: any;
}
interface WebSocketEventListener {
(evt: WebSocketEvent): void;
}
// @ts-ignore
class WebSocketEventTarget {
events: { [type: string]: WebSocketEventListener[]} = {};
dispatchEvent(event: WebSocketEvent) {
const list = this.events[event.type];
if (!list) {
return;
}
for (const l of list) {
l(event);
}
}
addEventListener(type: string, f: WebSocketEventListener) {
let list = this.events[type];
if (!list) {
list = this.events[type] = [];
}
list.push(f);
}
removeEventListener(type: string, f: WebSocketEventListener) {
const list = this.events[type];
if (!list) {
return;
}
const index = list.indexOf(f);
if (index > -1) {
list.splice(index, 1);
}
}
}
function defineEventAttribute(p: any, type: string) {
Object.defineProperty(p, 'on' + type, {
get: function () {
throw new Error(`${type} is write only`);
},
set: function (f) {
this.events[type] = [f];
}
});
}
interface WebSocketEndCallback {
(): void;
}
interface WebSocketErrorCallback {
(e: Error): void;
}
interface WebSocketDataCallback {
(data: string | ArrayBufferLike): void;
}
interface WebSocketSend {
(message: string|ArrayBufferLike): void;
}
interface WebSocketConnectCallback {
(e: Error, ws: any, send: WebSocketSend): void;
}
interface WebSocketConnect {
(url: string, protocols: string[],
connect: WebSocketConnectCallback,
end: WebSocketEndCallback,
error: WebSocketErrorCallback,
data: WebSocketDataCallback): void;
}
export function createWebSocketClass(__websocketConnect: WebSocketConnect) {
// @ts-ignore
class WebSocket extends WebSocketEventTarget {
_url: string;
_protocols: string[];
readyState: number;
send: (message: string|ArrayBufferLike) => void;
_ws: any;
constructor(url: string, protocols?: string[]) {
super();
this._url = url;
this._protocols = protocols;
this.readyState = 0;
__websocketConnect(url, protocols, (e, ws, send) => {
// connect
if (e != null) {
this.dispatchEvent({
type: 'error',
message: e.toString(),
});
return;
}
this._ws = ws;
this.send = send;
this.readyState = 1;
this.dispatchEvent({
type: 'open',
});
}, () => {
// end
this.readyState = 3;
this.dispatchEvent({
type: 'close',
reason: 'closed',
});
}, (e: Error) => {
// error
this.readyState = 3;
this.dispatchEvent({
type: 'error',
message: e.toString(),
});
}, (data: string | ArrayBufferLike) => {
// data
this.dispatchEvent({
type: 'message',
data: data,
source: this,
});
});
}
get url() {
return this._url;
}
get extensions() {
return "";
}
close() {
this._ws.close();
}
}
defineEventAttribute(WebSocket.prototype, "close");
defineEventAttribute(WebSocket.prototype, "error");
defineEventAttribute(WebSocket.prototype, "message");
defineEventAttribute(WebSocket.prototype, "open");
return WebSocket;
}