workers-sdk
workers-sdk copied to clipboard
🐛 BUG: `wrangler dev` does not propagate WebSocket close `code` and `reason`
What version of Wrangler are you using?
2.0.29
What operating system are you using?
Mac
Describe the Bug
When returning a WebSocket Response from a worker, wrangler dev does not correctly proxy the close code and reason from either the worker to the client, or the client to the worker. Instead it always defaults to a code of 1000 and an empty reason.
Example: Closing from Worker
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response(
`<!DOCTYPE html>
<html>
<body>
<script>
const url = new URL("/ws", window.origin);
url.protocol = url.protocol.replace("http", "ws");
const webSocket = new WebSocket(url);
webSocket.addEventListener("open", () => {
console.log("open");
});
webSocket.addEventListener("close", (event) => {
console.log("close", event.code, event.reason);
});
</script>
</body>
</html>
`,
{ headers: { "Content-Type": "text/html; charset=utf-8" } }
);
} else if (url.pathname === "/ws") {
const [client, worker] = Object.values(new WebSocketPair());
worker.accept();
ctx.waitUntil(
scheduler.wait(3000).then(() => worker.close(3001, "Worker Close"))
);
return new Response(null, { status: 101, webSocket: client });
} else {
return new Response(null, { status: 404 });
}
},
};
Running wrangler dev, visiting http://localhost:8787, logs open in the browser, then close 1000 <empty string> 3 seconds later. Publishing the same worker logs close 3001 Worker Close as expected.
Example: Closing from Client
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response(
`<!DOCTYPE html>
<html>
<body>
<script>
const url = new URL("/ws", window.origin);
url.protocol = url.protocol.replace("http", "ws");
const webSocket = new WebSocket(url);
webSocket.addEventListener("open", () => {
console.log("open");
setTimeout(() => {
webSocket.close(3002, "Client Close");
}, 3000);
});
</script>
</body>
</html>
`,
{ headers: { "Content-Type": "text/html; charset=utf-8" } }
);
} else if (url.pathname === "/ws") {
const [client, worker] = Object.values(new WebSocketPair());
worker.accept();
let closeResolve;
const closePromise = new Promise((resolve) => (closeResolve = resolve));
worker.addEventListener("close", (event) => {
console.log(event.code, event.reason);
closeResolve();
});
ctx.waitUntil(closePromise);
return new Response(null, { status: 101, webSocket: client });
} else {
return new Response(null, { status: 404 });
}
},
};
Running wrangler dev, visiting http://localhost:8787, logs 1000 in the terminal 3 seconds later. Publishing the same worker, then tailing, logs 3002 Client Close in the terminal instead as expected.