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

hmr websocket failed when use server.middlewareMod and HTTP2 #1807

Closed
TrungRueta opened this issue Jan 30, 2021 · 2 comments
Closed

hmr websocket failed when use server.middlewareMod and HTTP2 #1807

TrungRueta opened this issue Jan 30, 2021 · 2 comments

Comments

@TrungRueta
Copy link

Describe the bug

We have instruction Backend intergration how to setup backend use express or simillar framwork as base and i success setup one use fastify. Document is clear, and not much step to do so it easy.

I use fastify because i need use HTTP2 feature where express 4 not support yet. Fastify has well document and they has a chapter to explain how to compability express middleware into fastify

Will be best if we can meantion fastify in document as optional node framwork compability with vite ;).

Now, when setup fastify working with http2 done, i see hmr websocket stop working. It response with status code ERROR_PROTOCOL which meantion me to issue certification error.

After 2 days try cases, i found issue because HMR websocket server created with missing config.

Default hmr websocket use same server with vite dev server to working. It allow vite config https (http2) no issue. When dev server has http2 certification, hmr have too.

When set config.server.middlewareMode = true and config.server.https.{cert|key}, hmr will be failed because it require create standalone server but not pull config server from vite config append to Websocket server instance. It also can not reference vite dev server because it null (not created).

In almost cases we develop project use default http then we no see this issue, but when change to use http2 it require provide certificate and hmr bug comes.

This is example config http2 in vite.

const cert = readFileSync('localhost.pem', 'utf-8');
const key = readFileSync('localhost-key.pem', 'utf-8');

const viteConfig = defineConfig({
    server: {
       https: { cert, key }
   }
})

I found where we create websocket server:

ws.ts

if (server) {
    wss = new WebSocket.Server({ noServer: true })
    server.on('upgrade', (req, socket, head) => {
      if (req.headers['sec-websocket-protocol'] === HMR_HEADER) {
        wss.handleUpgrade(req, socket, head, (ws) => {
          wss.emit('connection', ws, req)
        })
      }
    })
  } else {
    // vite dev server in middleware mode.
// HERE WE ONLY CHECK CONDITION PORT BUT FORGOT ORTHER SERVER CONFIG LIKE CERT - KEY.
    wss = new WebSocket.Server({
      port:
        (typeof config.server.hmr === 'object' && config.server.hmr.port) ||
        24678
    })
  }

Please read ws document package at certificate config:

ws package

const https = require('https');
const WebSocket = require('ws');

const server = https.createServer({
  cert: fs.readFileSync('/path/to/cert.pem'),
  key: fs.readFileSync('/path/to/key.pem')
});
const wss = new WebSocket.Server({ server });

Reproduction

  • we need use mkcert to create CA local in computer, then generate local key+cert pem file for project, please read mkcert document to install.

Run command in project foldre to create key + cert file:

mkcert localhost

We will have 2 file localhost.pem and localhost-key.pem;

case 1 SPA standalone

  • use npm init @vitejs/app to create new project
  • create pem files.
  • config vite.config.js at server.https.{cert|key} as example above
  • run site,
  • from chrome dev tool -> network tab see column protocol, make sure h2 value show on
  • site work ok

case 2 add fastify backend

  • on same project now create new folder server, add fastify setup (use same cert - key pem for http2).
  • change config forllow instruction Backend intergration
  • run site, see protocol failed.

System Info

  • vite version: v2.0.0-beta.57
  • Operating System: Macos 10.14.6
  • Node version: 14.15.1
  • Package manager (npm/yarn/pnpm) and version: npm 6.14.11

i will try to setup sample project fastify and vite to show better issue later because i'm getting a little busy :(. Will update later.
Hope my explains is enough to hep you guys counter bug.

For now workaround for backend intergration + http2 is running vite dev server inside server node, (not use middleware, use listen). But is still not good because still need config second port for UI.

@airhorns
Copy link
Contributor

I think #1992 will fix this

@nihalgonsalves
Copy link
Member

Resolved by #1992. @TrungRueta please respond here if this is still an issue :)

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants