mirror of
https://github.com/by-sonic/tglock.git
synced 2026-11-05 15:21:55 +03:00
fix(worker): туннели через Worker рвались с 1003 на новых compatibility date; 2.0.0-beta.16 (#63)
* worker: set binaryType = "arraybuffer" to fix 1003 "binary messages required" Since compatibility date 2026-03-17 Cloudflare delivers binary WebSocket messages as Blob (websocket_standard_binary_type). The message handler accepts only ArrayBuffer and closes every tunnel with 1003. Setting binaryType before accept() restores ArrayBuffer delivery regardless of the compatibility date. * fix(worker): accept Blob frames and name an outdated Worker in the log; 2.0.0-beta.16 Since compatibility date 2026-03-17 Cloudflare delivers binary WebSocket frames as Blob unless binaryType is "arraybuffer", and the Worker closed every tunnel with 1003 right after the handshake. wrangler.toml itself pins 2026-09-19, so every fresh deployment was broken (#58, #50, #53). On top of #61 (binaryType before accept) the Worker now also relays Blob frames in order, and the client log tells the user to redeploy the script when a Worker closes with "1003 binary messages required". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Dmitry Sankevich <16187308+avost@users.noreply.github.com> Co-authored-by: babin <Thartewerner536e@engineer.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+17
-8
@@ -85,6 +85,7 @@ export default {
|
||||
}
|
||||
|
||||
const [client, server] = Object.values(new WebSocketPair());
|
||||
server.binaryType = "arraybuffer";
|
||||
server.accept();
|
||||
|
||||
const writer = upstream.writable.getWriter();
|
||||
@@ -116,28 +117,36 @@ export default {
|
||||
|
||||
server.addEventListener("message", (event) => {
|
||||
if (closed) return;
|
||||
if (!(event.data instanceof ArrayBuffer) && !ArrayBuffer.isView(event.data)) {
|
||||
const data = event.data;
|
||||
// С compatibility date 2026-03-17 бинарные кадры приходят как Blob, если
|
||||
// binaryType не "arraybuffer". Свойство выставлено выше; Blob всё равно
|
||||
// принимается — на случай рантайма, который его не учитывает. Раньше такой
|
||||
// кадр закрывал туннель кодом 1003 сразу после рукопожатия.
|
||||
const blob = typeof Blob !== "undefined" && data instanceof Blob;
|
||||
if (!blob && !(data instanceof ArrayBuffer) && !ArrayBuffer.isView(data)) {
|
||||
shutdown(1003, "binary messages required");
|
||||
return;
|
||||
}
|
||||
const chunk = event.data instanceof ArrayBuffer
|
||||
? new Uint8Array(event.data)
|
||||
: new Uint8Array(event.data.buffer, event.data.byteOffset, event.data.byteLength);
|
||||
if (pendingBytes + chunk.byteLength > MAX_PENDING_BYTES || pendingMessages >= MAX_PENDING_MESSAGES) {
|
||||
const chunk = blob ? null : data instanceof ArrayBuffer
|
||||
? new Uint8Array(data)
|
||||
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
||||
const size = blob ? data.size : chunk.byteLength;
|
||||
if (pendingBytes + size > MAX_PENDING_BYTES || pendingMessages >= MAX_PENDING_MESSAGES) {
|
||||
shutdown(1009, "Telegram write queue full");
|
||||
return;
|
||||
}
|
||||
pendingBytes += chunk.byteLength;
|
||||
pendingBytes += size;
|
||||
pendingMessages += 1;
|
||||
pending = pending
|
||||
.then(async () => {
|
||||
if (closed) return;
|
||||
const bytes = chunk || new Uint8Array(await data.arrayBuffer());
|
||||
await writer.ready;
|
||||
if (!closed) await writer.write(chunk);
|
||||
if (!closed) await writer.write(bytes);
|
||||
})
|
||||
.catch(() => shutdown(1011, "Telegram write failed"))
|
||||
.finally(() => {
|
||||
pendingBytes -= chunk.byteLength;
|
||||
pendingBytes -= size;
|
||||
pendingMessages -= 1;
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user