mirror of
https://github.com/MercuryWorkshop/bare-mux.git
synced 2025-05-14 06:40:02 -04:00
greatly simplify createwebsocket
This commit is contained in:
parent
ea21f222be
commit
abec64ef97
3 changed files with 69 additions and 146 deletions
|
@ -26,7 +26,6 @@
|
|||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-inject": "^5.0.5",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"rollup": "^4.9.6",
|
||||
|
|
|
@ -121,10 +121,9 @@ export class BareClient {
|
|||
createWebSocket(
|
||||
remote: string | URL,
|
||||
protocols: string | string[] | undefined = [],
|
||||
webSocketImpl?: WebSocketImpl,
|
||||
__deprecated_donotuse_websocket?: any,
|
||||
requestHeaders?: BareHeaders,
|
||||
arrayBufferImpl?: ArrayBuffer,
|
||||
): WebSocket {
|
||||
): BareWebSocket {
|
||||
try {
|
||||
remote = new URL(remote);
|
||||
} catch (err) {
|
||||
|
@ -148,7 +147,6 @@ export class BareClient {
|
|||
`Failed to construct 'WebSocket': The subprotocol '${proto}' is invalid.`
|
||||
);
|
||||
|
||||
arrayBufferImpl = arrayBufferImpl || (webSocketImpl || WebSocket).constructor.constructor("return ArrayBuffer")().prototype;
|
||||
requestHeaders = requestHeaders || {};
|
||||
requestHeaders['Host'] = (new URL(remote)).host;
|
||||
// requestHeaders['Origin'] = origin;
|
||||
|
@ -158,9 +156,9 @@ export class BareClient {
|
|||
// requestHeaders['User-Agent'] = navigator.userAgent;
|
||||
requestHeaders['Connection'] = 'Upgrade';
|
||||
|
||||
const socket = new BareWebSocket(remote, protocols, this.worker, requestHeaders, arrayBufferImpl)
|
||||
const socket = new BareWebSocket(remote, protocols, this.worker, requestHeaders);
|
||||
|
||||
return socket as unknown as WebSocket;
|
||||
return socket;
|
||||
}
|
||||
|
||||
async fetch(
|
||||
|
|
204
src/websocket.ts
204
src/websocket.ts
|
@ -3,150 +3,76 @@ import { WebSocketFields } from "./snapshot";
|
|||
import { BareHeaders } from "./baretypes";
|
||||
|
||||
export class BareWebSocket extends EventTarget {
|
||||
url: string;
|
||||
protocols: string | string[] | undefined = [];
|
||||
readyState: number = WebSocketFields.CONNECTING;
|
||||
binaryType = "blob";
|
||||
url: string;
|
||||
|
||||
//legacy event handlers
|
||||
onopen = null;
|
||||
onerror = null;
|
||||
onmessage = null;
|
||||
onclose = null;
|
||||
|
||||
channel: MessageChannel;
|
||||
constructor(
|
||||
remote: string | URL,
|
||||
protocols: string | string[] | undefined = [],
|
||||
worker: WorkerConnection,
|
||||
requestHeaders?: BareHeaders,
|
||||
arrayBufferImpl?: ArrayBuffer,
|
||||
) {
|
||||
super();
|
||||
this.url = remote.toString();
|
||||
this.protocols = protocols;
|
||||
|
||||
const onopen = (protocol: string) => {
|
||||
this.readyState = WebSocketFields.OPEN;
|
||||
this.protocols = protocol;
|
||||
channel: MessageChannel;
|
||||
constructor(
|
||||
remote: string | URL,
|
||||
public protocols: string | string[] | undefined = [],
|
||||
worker: WorkerConnection,
|
||||
requestHeaders?: BareHeaders,
|
||||
) {
|
||||
super();
|
||||
this.url = remote.toString();
|
||||
this.protocols = protocols;
|
||||
|
||||
(this as any).meta = {
|
||||
headers: {
|
||||
"sec-websocket-protocol": protocol,
|
||||
}
|
||||
};
|
||||
const event = new Event("open")
|
||||
this.dispatchEvent(event);
|
||||
if (this.onopen) {
|
||||
this.onopen(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onmessage = async (payload) => {
|
||||
if (typeof payload === "string") {
|
||||
} else if ("byteLength" in payload) {
|
||||
if (this.binaryType === "blob") {
|
||||
payload = new Blob([payload]);
|
||||
} else {
|
||||
Object.setPrototypeOf(payload, arrayBufferImpl);
|
||||
}
|
||||
} else if ("arrayBuffer" in payload) {
|
||||
if (this.binaryType === "arraybuffer") {
|
||||
payload = await payload.arrayBuffer()
|
||||
Object.setPrototypeOf(payload, arrayBufferImpl);
|
||||
}
|
||||
}
|
||||
const onopen = (protocol: string) => {
|
||||
this.protocols = protocol;
|
||||
|
||||
const event = new MessageEvent("message", {data: payload });
|
||||
this.dispatchEvent(event);
|
||||
if (this.onmessage) {
|
||||
this.onmessage(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onclose = (code: number, reason: string) => {
|
||||
this.readyState = WebSocketFields.CLOSED;
|
||||
const event = new CloseEvent("close", { code, reason })
|
||||
this.dispatchEvent(event);
|
||||
if (this.onclose) {
|
||||
this.onclose(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onerror = () => {
|
||||
this.readyState = WebSocketFields.CLOSED;
|
||||
const event = new Event("error");
|
||||
this.dispatchEvent(event);
|
||||
if (this.onerror) {
|
||||
this.onerror(event);
|
||||
};
|
||||
};
|
||||
|
||||
this.channel = new MessageChannel();
|
||||
|
||||
this.channel.port1.onmessage = event => {
|
||||
if (event.data.type === "open") {
|
||||
onopen(event.data.args[0]);
|
||||
} else if (event.data.type === "message") {
|
||||
onmessage(event.data.args[0]);
|
||||
} else if (event.data.type === "close") {
|
||||
onclose(event.data.args[0], event.data.args[1]);
|
||||
} else if (event.data.type === "error") {
|
||||
onerror(/* event.data.args[0] */);
|
||||
}
|
||||
}
|
||||
|
||||
worker.sendMessage({
|
||||
type: "websocket",
|
||||
websocket: {
|
||||
url: remote.toString(),
|
||||
origin: origin,
|
||||
//@ts-expect-error
|
||||
protocols: protocols,
|
||||
requestHeaders: requestHeaders,
|
||||
channel: this.channel.port2,
|
||||
},
|
||||
}, [this.channel.port2])
|
||||
}
|
||||
|
||||
send(...args) {
|
||||
if (this.readyState === WebSocketFields.CONNECTING) {
|
||||
throw new DOMException(
|
||||
"Failed to execute 'send' on 'WebSocket': Still in CONNECTING state."
|
||||
);
|
||||
}
|
||||
const event = new Event("open")
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
let data = args[0];
|
||||
if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
||||
const onmessage = async (payload) => {
|
||||
const event = new MessageEvent("message", { data: payload });
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
this.channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []);
|
||||
}
|
||||
|
||||
close(code, reason) {
|
||||
this.readyState = WebSocketFields.CLOSING;
|
||||
this.channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason });
|
||||
}
|
||||
|
||||
get bufferedAmount() {
|
||||
return 0;
|
||||
}
|
||||
get protocol() {
|
||||
if (Array.isArray(this.protocols)) {
|
||||
return this.protocols[0] || "";
|
||||
} else {
|
||||
return this.protocols || "";
|
||||
const onclose = (code: number, reason: string) => {
|
||||
const event = new CloseEvent("close", { code, reason })
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
const onerror = () => {
|
||||
const event = new Event("error");
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
this.channel = new MessageChannel();
|
||||
|
||||
this.channel.port1.onmessage = event => {
|
||||
if (event.data.type === "open") {
|
||||
onopen(event.data.args[0]);
|
||||
} else if (event.data.type === "message") {
|
||||
onmessage(event.data.args[0]);
|
||||
} else if (event.data.type === "close") {
|
||||
onclose(event.data.args[0], event.data.args[1]);
|
||||
} else if (event.data.type === "error") {
|
||||
onerror(/* event.data.args[0] */);
|
||||
}
|
||||
}
|
||||
get extensions() {
|
||||
return "";
|
||||
}
|
||||
|
||||
worker.sendMessage({
|
||||
type: "websocket",
|
||||
websocket: {
|
||||
url: remote.toString(),
|
||||
origin: origin,
|
||||
//@ts-expect-error
|
||||
protocols: protocols,
|
||||
requestHeaders: requestHeaders,
|
||||
channel: this.channel.port2,
|
||||
},
|
||||
}, [this.channel.port2])
|
||||
}
|
||||
|
||||
send(...args) {
|
||||
let data = args[0];
|
||||
if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
||||
|
||||
this.channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []);
|
||||
}
|
||||
|
||||
close(code, reason) {
|
||||
this.channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason });
|
||||
}
|
||||
}
|
||||
//@ts-expect-error have to do this
|
||||
BareWebSocket.prototype.CONNECTING = WebSocketFields.CONNECTING;
|
||||
//@ts-expect-error have to do this
|
||||
BareWebSocket.prototype.OPEN = WebSocketFields.OPEN;
|
||||
//@ts-expect-error have to do this
|
||||
BareWebSocket.prototype.CLOSING = WebSocketFields.CLOSING;
|
||||
//@ts-expect-error have to do this
|
||||
BareWebSocket.prototype.CLOSED = WebSocketFields.CLOSED;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue