rsnext/packages/next/server/lib/start-server.ts
JJ Kasper 75748caf7f
Migrate server-sent events HMR connection to WebSocket (#29903)
This replaces the server-sent events HMR connection with a WebSocket connection to prevent hitting browser connection limits, allow sending events back from the browser, and overall better performance. 

This approach sets up the the `upgrade` event listener on the server immediately when created via `next dev` and on the first request using `req.socket.server` when created via a custom server. In a follow-up PR we can push the files changed via the WebSocket as well. 

x-ref: https://github.com/vercel/next.js/issues/10061
x-ref: https://github.com/vercel/next.js/issues/8064
x-ref: https://github.com/vercel/next.js/issues/4495

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes
2021-10-15 07:09:54 +00:00

33 lines
932 B
TypeScript

import http from 'http'
import next from '../next'
export default async function start(
serverOptions: any,
port?: number,
hostname?: string
) {
let requestHandler: ReturnType<typeof app.getRequestHandler>
const srv = http.createServer((req, res) => {
return requestHandler(req, res)
})
const app = next({
...serverOptions,
customServer: false,
httpServer: srv,
})
requestHandler = app.getRequestHandler()
await new Promise<void>((resolve, reject) => {
// This code catches EADDRINUSE error if the port is already in use
srv.on('error', reject)
srv.on('listening', () => resolve())
srv.listen(port, hostname)
})
// It's up to caller to run `app.prepare()`, so it can notify that the server
// is listening before starting any intensive operations.
const addr = srv.address()
return {
app,
actualPort: addr && typeof addr === 'object' ? addr.port : port,
}
}