Open e3dio opened 9 months ago
Which platform is this? I'm running the same on an M1 mac and I get a 9ms timeout.
$ deno run -A /tmp/ws.ts
Listening on http://localhost:3007/
ws open: 4ms
I tried Linux and was only 8ms, I get 2050ms on Windows
Do you have any sort of firewall process running on Windows? It may also be some weird interaction with the event loop but it's probably worth ruling out any firewall.
No firewall, it connects instantly when I manually connect with TCP and do websocket handshake:
const port = 3007;
const server = Deno.serve({ port }, req => {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onopen = () => console.timeEnd('ws open');
return response;
});
console.time('ws open');
const tcp = await Deno.connect({ port });
await tcp.writable.getWriter().write(
new TextEncoder().encode([
"GET / HTTP/1.1",
"connection: upgrade",
"upgrade: websocket",
"sec-websocket-key: SGVsbG8sIHdvcmxkIQ==",
"\n",
].join("\n")),
);
ws open: 3ms
Interesting. It sounds like Tokio isn't waking up when it should. Thanks for the info.
deno 1.40.4 Windows11
const port = 3007;
const server = Deno.serve({ port }, req => {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onopen = () => console.timeEnd('ws open');
return response;
});
console.time('ws open');
const ws = new WebSocket(`ws://localhost:${port}`);
ws open: 2022ms
const port = 3007;
const server = Deno.serve({ port }, req => {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onopen = () => console.timeEnd('ws open');
return response;
});
console.time('ws open');
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
ws open: 3ms
I see the same, 127.0.0.1
gives 2ms, localhost
gives 2050ms. I tried fetch
instead of new WebSocket()
and I get 310ms for localhost
and 2ms for 127.0.0.1
, so WebSocket is taking extra long for some reason, and not sure why localhost is slower for both. But I can use 127.0.0.1
for now so I don't have to wait 2 seconds :)
const port = 3007;
const server = Deno.serve({ port }, r => new Response());
console.time();
await fetch(`http://localhost:${port}`);
console.timeEnd();
console.time();
await fetch(`http://127.0.0.1:${port}`);
console.timeEnd();
default: 310ms default: 2ms
If you Google "localhost slow windows" it turns up a bunch of results from different servers of different kinds and makes. I think this might be a fairly "known" Windows thing. One possibility is that localhost ends up resolving to the IPv6 address? Or then again if may be something completely unrelated to that.
I tried new WebSocket('ws://localhost')
from different client (chrome browser) and I get 310ms, same for fetch. 127.0.0.1
is 2ms. So Deno WebSocket is taking 1700ms longer for some reason than other clients on localhost
Have noticed that explicitly setting hostname to localhost
when listening seems to resolve the issue.
// ensure hostname is set (omitting the hostname results in 2000ms connection times)
await Deno.serve({ port: 5000, hostname: 'localhost' }, request => {
const { response, socket } = Deno.upgradeWebSocket(request)
socket.addEventListener('open', () => console.log('server open'))
return response
})
// measure time to open: (around 8ms)
console.time('client open')
const socket = new WebSocket('ws://localhost:5000')
socket.addEventListener('open', () => console.timeEnd('client open'))
Not entirely sure what the issue is, but assume windows is having problems differentiating between IPv4 and IPv6 on localhost. If omitting the hostname, you can attain similar performance by passing just passing a IPv4 loopback address.
await Deno.serve({ port: 5000 }, request => { ... }) // omit hostname
console.time('client open')
const socket = new WebSocket('ws://127.0.0.1:5000') // around 8ms
socket.addEventListener('open', () => console.timeEnd('client open'))
Is this still a Deno bug? (it is curious this issue would be specific to WebSocket connections). Also, would it make sense for Deno to automatically assign the hostname
option to localhost
if not specified by the user?
Version: Deno 1.40.4
Why does
new WebSocket()
take 2 seconds to open a connection ? It should be instant