Browser Dialer: Change from ES5 to ES6+ for performance (#3832)

This commit is contained in:
Lumière Élevé 2024-09-19 09:57:43 +01:00 committed by GitHub
parent bc28cad8f8
commit 7677ac980d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5,132 +5,141 @@
</head> </head>
<body> <body>
<script> <script>
"use strict";
// Enable a much more aggressive JIT for performance gains
// Copyright (c) 2021 XRAY. Mozilla Public License 2.0. // Copyright (c) 2021 XRAY. Mozilla Public License 2.0.
var url = "ws://" + window.location.host + "/websocket?token=csrfToken"; let url = "ws://" + window.location.host + "/websocket?token=csrfToken";
var clientIdleCount = 0; let clientIdleCount = 0;
var upstreamGetCount = 0; let upstreamGetCount = 0;
var upstreamWsCount = 0; let upstreamWsCount = 0;
var upstreamPostCount = 0; let upstreamPostCount = 0;
setInterval(check, 1000); let check = function () {
function check() {
if (clientIdleCount > 0) { if (clientIdleCount > 0) {
return; return;
} };
clientIdleCount += 1; clientIdleCount += 1;
console.log("Prepare", url); console.log("Prepare", url);
var ws = new WebSocket(url); let ws = new WebSocket(url);
// arraybuffer is significantly faster in chrome than default // arraybuffer is significantly faster in chrome than default
// blob, tested with chrome 123 // blob, tested with chrome 123
ws.binaryType = "arraybuffer"; ws.binaryType = "arraybuffer";
ws.onmessage = function (event) { ws.addEventListener("message", (event) => {
clientIdleCount -= 1; clientIdleCount -= 1;
let [method, url, protocol] = event.data.split(" "); let [method, url, protocol] = event.data.split(" ");
if (method == "WS") { switch (method) {
upstreamWsCount += 1; case "WS": {
console.log("Dial WS", url, protocol); upstreamWsCount += 1;
const wss = new WebSocket(url, protocol); console.log("Dial WS", url, protocol);
wss.binaryType = "arraybuffer"; const wss = new WebSocket(url, protocol);
var opened = false; wss.binaryType = "arraybuffer";
ws.onmessage = function (event) { let opened = false;
wss.send(event.data) ws.onmessage = function (event) {
} wss.send(event.data)
wss.onopen = function (event) { };
opened = true; wss.onopen = function (event) {
ws.send("ok") opened = true;
} ws.send("ok")
wss.onmessage = function (event) { };
ws.send(event.data) wss.onmessage = function (event) {
} ws.send(event.data)
wss.onclose = function (event) { };
upstreamWsCount -= 1; wss.onclose = function (event) {
console.log("Dial WS DONE, remaining: ", upstreamWsCount); upstreamWsCount -= 1;
ws.close() console.log("Dial WS DONE, remaining: ", upstreamWsCount);
} ws.close()
wss.onerror = function (event) { };
!opened && ws.send("fail") wss.onerror = function (event) {
wss.close() !opened && ws.send("fail")
} wss.close()
ws.onclose = function (event) { };
wss.close() ws.onclose = function (event) {
} wss.close()
} else if (method == "GET") { };
(async () => { break;
console.log("Dial GET", url);
ws.send("ok");
const controller = new AbortController();
/*
Aborting a streaming response in JavaScript
requires two levers to be pulled:
First, the streaming read itself has to be cancelled using
reader.cancel(), only then controller.abort() will actually work.
If controller.abort() alone is called while a
reader.read() is ongoing, it will block until the server closes the
response, the page is refreshed or the network connection is lost.
*/
let reader = null;
ws.onclose = (event) => {
try {
reader && reader.cancel();
} catch(e) {}
try {
controller.abort();
} catch(e) {}
}
try {
upstreamGetCount += 1;
const response = await fetch(url, {signal: controller.signal});
const body = await response.body;
reader = body.getReader();
while (true) {
const { done, value } = await reader.read();
ws.send(value);
if (done) break;
}
} finally {
upstreamGetCount -= 1;
console.log("Dial GET DONE, remaining: ", upstreamGetCount);
ws.close();
}
})()
} else if (method == "POST") {
upstreamPostCount += 1;
console.log("Dial POST", url);
ws.send("ok");
ws.onmessage = async (event) => {
try {
const response = await fetch(
url,
{method: "POST", body: event.data}
);
if (response.ok) {
ws.send("ok");
} else {
console.error("bad status code");
ws.send("fail");
}
} finally {
upstreamPostCount -= 1;
console.log("Dial POST DONE, remaining: ", upstreamPostCount);
ws.close();
}
}; };
} case "GET": {
(async () => {
console.log("Dial GET", url);
ws.send("ok");
const controller = new AbortController();
check() /*
} Aborting a streaming response in JavaScript
ws.onerror = function (event) { requires two levers to be pulled:
ws.close()
} First, the streaming read itself has to be cancelled using
} reader.cancel(), only then controller.abort() will actually work.
If controller.abort() alone is called while a
reader.read() is ongoing, it will block until the server closes the
response, the page is refreshed or the network connection is lost.
*/
let reader = null;
ws.onclose = (event) => {
try {
reader && reader.cancel();
} catch(e) {};
try {
controller.abort();
} catch(e) {};
};
try {
upstreamGetCount += 1;
const response = await fetch(url, {signal: controller.signal});
const body = await response.body;
reader = body.getReader();
while (true) {
const { done, value } = await reader.read();
ws.send(value);
if (done) break;
};
} finally {
upstreamGetCount -= 1;
console.log("Dial GET DONE, remaining: ", upstreamGetCount);
ws.close();
};
})();
break;
};
case "POST": {
upstreamPostCount += 1;
console.log("Dial POST", url);
ws.send("ok");
ws.onmessage = async (event) => {
try {
const response = await fetch(
url,
{method: "POST", body: event.data}
);
if (response.ok) {
ws.send("ok");
} else {
console.error("bad status code");
ws.send("fail");
};
} finally {
upstreamPostCount -= 1;
console.log("Dial POST DONE, remaining: ", upstreamPostCount);
ws.close();
};
};
break;
};
};
check();
});
ws.addEventListener("error", (event) => {
ws.close();
});
};
let checkTask = setInterval(check, 1000);
</script> </script>
</body> </body>
</html> </html>