ws async works

This commit is contained in:
rustdesk 2022-01-19 22:26:23 +08:00
parent b18da1fb39
commit 85ec94e36c

View File

@ -7,55 +7,115 @@ type Keys = "message" | "open" | "close" | "error";
export default class Websock { export default class Websock {
_websocket: WebSocket; _websocket: WebSocket;
_eventHandlers: { [key in Keys]: Function }; _eventHandlers: { [key in Keys]: Function };
_buf: Uint8Array[];
_status: any;
send_message(msg: message.Message) { constructor(uri: string) {
this._websocket.send(message.Message.encode(msg).finish()); this._eventHandlers = {
message: (_: any) => {},
open: () => {},
close: () => {},
error: () => {},
};
this._status = "";
this._buf = [];
this._websocket = new WebSocket(uri);
this._websocket.onmessage = this._recv_message.bind(this);
this._websocket.binaryType = "arraybuffer";
} }
send_rendezvous(msg: rendezvous.RendezvousMessage) { sendMessage(data: any) {
this._websocket.send(rendezvous.RendezvousMessage.encode(msg).finish()); this._websocket.send(
message.Message.encode(message.Message.fromJSON(data)).finish()
);
}
sendRendezvous(data: any) {
this._websocket.send(
rendezvous.RendezvousMessage.encode(
rendezvous.RendezvousMessage.fromJSON(data)
).finish()
);
}
parseMessage(data: Uint8Array) {
return message.Message.decode(data);
}
parseRendezvous(data: Uint8Array) {
return rendezvous.RendezvousMessage.decode(data);
} }
// Event Handlers // Event Handlers
off(evt: Keys) { off(evt: Keys) {
this._eventHandlers[evt] = () => { }; this._eventHandlers[evt] = () => {};
} }
on(evt: Keys, handler: Function) { on(evt: Keys, handler: Function) {
this._eventHandlers[evt] = handler; this._eventHandlers[evt] = handler;
} }
constructor(uri: string, protocols: string) { async open(timeout: number = 12000): Promise<Websock> {
this._eventHandlers = { return new Promise((resolve, reject) => {
message: (_: any) => { }, setTimeout(() => {
open: () => { }, if (this._status != "open") {
close: () => { }, reject(this._status || "timeout");
error: () => { }, }
}; }, timeout);
this._websocket.onopen = () => {
this._status = "open";
console.debug(">> WebSock.onopen");
if (this._websocket?.protocol) {
console.info(
"Server choose sub-protocol: " + this._websocket.protocol
);
}
this._websocket = new WebSocket(uri, protocols); this._eventHandlers.open();
console.debug("<< WebSock.onopen");
resolve(this);
};
this._websocket.onclose = (e) => {
this._status = e;
console.debug(">> WebSock.onclose");
this._eventHandlers.close(e);
console.debug("<< WebSock.onclose");
reject(e);
};
this._websocket.onerror = (e) => {
this._status = e;
console.debug(">> WebSock.onerror: " + e);
this._eventHandlers.error(e);
console.debug("<< WebSock.onerror: " + e);
reject(e);
};
});
}
this._websocket.onmessage = this._recv_message.bind(this); async next(timeout = 12000): Promise<Uint8Array> {
this._websocket.binaryType = "arraybuffer"; let func = (
this._websocket.onopen = () => { resolve: (value: Uint8Array) => void,
console.debug(">> WebSock.onopen"); reject: (reason: any) => void,
if (this._websocket.protocol) { tm0: number
console.info("Server choose sub-protocol: " + this._websocket.protocol); ) => {
if (this._buf.length) {
resolve(this._buf[0]);
this._buf.splice(0, 1);
} else {
if (this._status != 'open') {
reject(this._status);
return;
}
if (new Date().getTime() > tm0 + timeout) {
reject("timeout");
} else {
setTimeout(() => func(resolve, reject, tm0), 1);
}
} }
this._eventHandlers.open();
console.debug("<< WebSock.onopen");
};
this._websocket.onclose = (e) => {
console.debug(">> WebSock.onclose");
this._eventHandlers.close(e);
console.debug("<< WebSock.onclose");
};
this._websocket.onerror = (e) => {
console.debug(">> WebSock.onerror: " + e);
this._eventHandlers.error(e);
console.debug("<< WebSock.onerror: " + e);
}; };
return new Promise((resolve, reject) => {
func(resolve, reject, new Date().getTime());
});
} }
close() { close() {
@ -68,13 +128,14 @@ export default class Websock {
this._websocket.close(); this._websocket.close();
} }
this._websocket.onmessage = () => { }; this._websocket.onmessage = () => {};
} }
} }
_recv_message(e: any) { _recv_message(e: any) {
if (e.data instanceof window.ArrayBuffer) { if (e.data instanceof window.ArrayBuffer) {
let bytes = new Uint8Array(e.data); let bytes = new Uint8Array(e.data);
this._buf.push(bytes);
} }
this._eventHandlers.message(e.data); this._eventHandlers.message(e.data);
} }
@ -86,14 +147,12 @@ export default class Websock {
} }
} }
/* let ws = new Websock("ws://207.148.17.15:21118");
let ws = new Websock('ws://207.148.17.15:21118');
await ws.open(); await ws.open();
console.log("ws connected"); console.log("ws connected");
// let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' }); // let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' });
// ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole })); // ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole }));
let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 }); let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 });
ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ testNatRequest })); ws.sendRendezvous({ testNatRequest });
let msg = await ws.next(); let msg = ws.parseRendezvous(await ws.next());
console.log(msg); console.log(msg);
*/