Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EADDRINUSE with WebSockets on file change #2903

Closed
Volper212 opened this issue Nov 24, 2021 · 7 comments
Closed

EADDRINUSE with WebSockets on file change #2903

Volper212 opened this issue Nov 24, 2021 · 7 comments

Comments

@Volper212
Copy link

Describe the bug

I'm trying to get WebSockets to work with SvelteKit. However, whenever I change the file the WebSocket server is created, the dev server crashes and says that the port is taken. So it appears like 2 servers are running at once at some point or the port remains open for some reason. I feel that this is not intended behaviour because if I restart the server the port is not taken anymore until I make a change in the file again.

Reproduction

Repository: https://github.com/Volper212/sveltekit-report

Steps:

  1. git clone https://github.com/Volper212/sveltekit-report
  2. cd sveltekit-report
  3. npm i
  4. npm run dev
  5. Open http://localhost:3000 in the browser
  6. Edit file src/routes/index.js in any way that causes a refresh (for example add a semicolon on line 2)

Logs

20:41:37 [vite] page reload src/routes/index.js
events.js:352
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE: address already in use :::8080
    at Server.setupListenHandle [as _listen2] (net.js:1320:16)
    at listenInCluster (net.js:1368:12)
    at Server.listen (net.js:1454:7)
    at new WebSocketServer (C:\Users\igor\sveltekit-report\node_modules\ws\lib\websocket-server.js:94:20)
    at eval (C:\Users\igor\sveltekit-report\src\routes\index.js:6:1)
    at async instantiateModule (C:\Users\igor\sveltekit-report\node_modules\vite\dist\node\chunks\dep-e0fe87f8.js:66544:9)
Emitted 'error' event on WebSocketServer instance at:
    at Server.emit (events.js:375:28)
    at Server.emit (domain.js:470:12)
    at emitErrorNT (net.js:1347:8)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  code: 'EADDRINUSE',
  errno: -4091,
  syscall: 'listen',
  address: '::',
  port: 8080
}

System Info

System:
    OS: Windows 10 10.0.19043
    CPU: (4) x64 Intel(R) Core(TM) i3-4005U CPU @ 1.70GHz
    Memory: 8.84 GB / 11.91 GB
  Binaries:
    Node: 14.17.3 - C:\Program Files\nodejs\node.EXE
    npm: 8.1.4 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (93.0.961.47)
    Internet Explorer: 11.0.19041.1202
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.3
    @sveltejs/kit: next => 1.0.0-next.199
    svelte: ^3.44.0 => 3.44.2

Severity

annoyance

Additional Information

No response

@bluwy
Copy link
Member

bluwy commented Nov 25, 2021

This is because of HMR in that endpoint that re-creates the websocket server whenever you update it. Ideally, you'd want to close and restart the server whenever you make updates. Try adding a HMR handler at the end of your file:

if (import.meta.hot) {
  import.meta.hot.dispose(() => {
    server.close() // or something similar 
  ))
}

Check the spec for more info.

@Volper212
Copy link
Author

I updated the repo, but the server still crashes after a change in the file.

@bluwy
Copy link
Member

bluwy commented Nov 30, 2021

My bad. You'd need to have import.meta.hot.accept() as well to tell Vite that the file accepts HMR updates.

Something like this should work:

if (import.meta.hot) {
    import.meta.hot.accept();
    import.meta.hot.dispose(() => {
        server.close();
    });
}

@Volper212
Copy link
Author

Unfortunately it still crashes when I reload the browser after a change. Repo updated again.

@bluwy
Copy link
Member

bluwy commented Dec 4, 2021

Hmm. If so I might be out of ideas, but last I tried that code, it worked for me locally.

@Rich-Harris
Copy link
Member

The underlying issue is vitejs/vite#7887. It's possible to work around it, if you can hold your nose:

if (globalThis.__server) {
  globalThis.__server.close();
}

const server = new WebSocketServer({ port: 8080 });
globalThis.__server = server;

Obviously you can wrap the relevant bits in if (import.meta.env.DEV) etc so that it gets removed in production, if you want.

@autr
Copy link

autr commented Apr 11, 2023

Yeah the Vite devs are on crack. Do not npm update if you are sensitive to flashing lights.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants