add websocket support to AdriftClient

This commit is contained in:
CoolElectronics 2023-08-13 19:59:15 -04:00
parent f5e0c4202e
commit 7f5234998b
No known key found for this signature in database
GPG key ID: F63593D168636C50
15 changed files with 552 additions and 36 deletions

View file

@ -6,6 +6,7 @@ import {
MetaCallback,
ReadyStateCallback,
WebSocketImpl,
WebSocketFields
} from "bare-client-custom";
import { Connection } from "./Connection";
@ -16,6 +17,16 @@ import { Connection } from "./Connection";
// }
// }
//
const WebSocketFields = {
prototype: {
send: WebSocket.prototype.send,
},
CLOSED: WebSocket.CLOSED,
CLOSING: WebSocket.CLOSING,
CONNECTING: WebSocket.CONNECTING,
OPEN: WebSocket.OPEN,
};
export class AdriftBareClient extends Client {
constructor(private connection: Connection) {
super();
@ -64,6 +75,109 @@ export class AdriftBareClient extends Client {
onReadyState: ReadyStateCallback,
webSocketImpl: WebSocketImpl
): WebSocket {
throw new Error("unimplemented");
const ws = new WebSocket("ws:null");
// this will error. that's okay
let send = this.connection.wsconnect(remote, () => {
onReadyState(WebSocketFields.OPEN);
ws.dispatchEvent(new Event('open'));
}, () => {
onReadyState(WebSocketFields.CLOSED);
ws.dispatchEvent(new Event('close'));
// what do i do for WebSocketFields.closing?
}, (data) => {
ws.dispatchEvent(new MessageEvent("message", {
data,
// might be other shit here idk
}));
});
// const cleanup = () => {
// ws.removeEventListener('close', closeListener);
// ws.removeEventListener('message', messageListener);
// };
// const closeListener = () => {
// cleanup();
// };
(ws as any).__defineGetter__("send", () => (data: any) => {
send(data);
});
(ws as any).__defineSetter__("send", () => { });
// ws.send = (data) => {
// console.log("sending data to server:" + data);
// };
// console.log(ws.send);
const messageListener = (event: MessageEvent) => {
// cleanup();
// // ws.binaryType is irrelevant when sending text
// if (typeof event.data !== 'string')
// throw new TypeError('the first websocket message was not a text frame');
// const message = JSON.parse(event.data) as SocketServerToClient;
// // finally
// if (message.type !== 'open')
// throw new TypeError('message was not of open type');
// event.stopImmediatePropagation();
// onMeta({
// protocol: message.protocol,
// setCookies: message.setCookies,
// });
// // now we want the client to see the websocket is open and ready to communicate with the remote
// onReadyState(WebSocketFields.OPEN);
ws.dispatchEvent(new Event('open'));
};
setTimeout(messageListener, 30);
// ws.addEventListener('close', closeListener);
ws.addEventListener('message', messageListener);
// // CONNECTED TO THE BARE SERVER, NOT THE REMOTE
// ws.addEventListener(
// 'open',
// (event) => {
// // we have to cancel this event because it doesn't reflect the connection to the remote
// // once we are actually connected to the remote, we can dispatch a fake open event.
// event.stopImmediatePropagation();
// // we need to fake the readyState value again so it remains CONNECTING
// // right now, it's open because we just connected to the remote
// // but we need to fake this from the client so it thinks it's still connecting
// onReadyState(WebSocketFields.CONNECTING);
// getRequestHeaders().then((headers) =>
// WebSocketFields.prototype.send.call(
// ws,
// JSON.stringify({
// type: 'connect',
// remote: remote.toString(),
// protocols,
// headers,
// forwardHeaders: [],
// } as SocketClientToServer)
// )
// );
// },
// // only block the open event once
// { once: true }
// );
return ws;
}
}