carlosV2 / adapter-node-ws

Adapter for SvelteKit apps that generates a standalone Node server with support for WebSockets.
MIT License
18 stars 4 forks source link

Suggestion: attach to vite development http server #4

Open eslym opened 1 year ago

eslym commented 1 year ago

you could just listen the upgrade event on the http server of vite development server and only handle the request when req.headers["sec-websocket-protocol"] !== "vite-hmr"

how i do it: https://github.com/eslym/vite-plugin-express-app/blob/ed1d3f3c520b3ac628a1134aa53bdc7b61578576/src/index.ts#L33

carlosV2 commented 1 year ago

Actually, this is a good idea! I'll definitely take a look at this.

Thank you very much!

pbk20191 commented 6 months ago

Writing code like below seems working with vite-hmr in the same port. But I'm not sure if this is the best implementation.

// plugin.js 
configureServer({ httpServer }) {
  const webSocketServer = new WebSocketServer({ server: httpServer });
  const original_imp = webSocketServer.handleUpgrade
  webSocketServer.handleUpgrade = (...args) => {
      if (args[0].headers['sec-websocket-protocol'] === 'vite-hmr') {
          return
      }
      return original_imp.bind(webSocketServer)(...args)
  }
  globalThis[Symbol.for(sym)] = webSocketServer
}

or should we hardcode like below?

configureServer({ httpServer }) {
      const webSocketServer = new WebSocketServer({ noServer:true });
      const emitConnection = webSocketServer.emit.bind(webSocketServer, 'connection');
      const listeners = {
        listening: webSocketServer.emit.bind(webSocketServer, 'listening'),
        error: webSocketServer.emit.bind(webSocketServer, 'error'),
        upgrade: (req, socket, head) => {
          if (req.headers['sec-websocket-protocol'] === 'vite-hmr') {
            return
          }
          console.log("start upgrade", req.headers)
          webSocketServer.handleUpgrade(req, socket, head, emitConnection)
        }
      }
      webSocketServer.options.server = httpServer
      webSocketServer._server = httpServer
      webSocketServer._removeListeners = addListeners(httpServer, listeners)
      webSocketServer.options.noServer = false
      globalThis[Symbol.for(sym)] = webSocketServer
    }

function addListeners(server, map) {
  for (const event of Object.keys(map)) server.on(event, map[event]);

  return function removeListeners() {
    for (const event of Object.keys(map)) {
      server.removeListener(event, map[event]);
    }
  };
}