Skip to content

Commit abe9274

Browse files
authoredApr 5, 2023
fix(server): delay ws server listen when restart (#12734)
1 parent 1ea38e2 commit abe9274

File tree

2 files changed

+44
-34
lines changed

2 files changed

+44
-34
lines changed
 

‎packages/vite/src/node/server/index.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,13 @@ export interface ResolvedServerUrls {
338338

339339
export async function createServer(
340340
inlineConfig: InlineConfig = {},
341+
): Promise<ViteDevServer> {
342+
return _createServer(inlineConfig, { ws: true })
343+
}
344+
345+
export async function _createServer(
346+
inlineConfig: InlineConfig = {},
347+
options: { ws: boolean },
341348
): Promise<ViteDevServer> {
342349
const config = await resolveConfig(inlineConfig, 'serve')
343350

@@ -699,6 +706,9 @@ export async function createServer(
699706
return listen(port, ...args)
700707
}) as any
701708
} else {
709+
if (options.ws) {
710+
ws.listen()
711+
}
702712
await initServer()
703713
}
704714

@@ -832,7 +842,8 @@ async function restartServer(server: ViteDevServer) {
832842

833843
let newServer = null
834844
try {
835-
newServer = await createServer(inlineConfig)
845+
// delay ws server listen
846+
newServer = await _createServer(inlineConfig, { ws: false })
836847
} catch (err: any) {
837848
server.config.logger.error(err.message, {
838849
timestamp: true,
@@ -864,6 +875,7 @@ async function restartServer(server: ViteDevServer) {
864875
server.printUrls()
865876
}
866877
} else {
878+
server.ws.listen()
867879
logger.info('server restarted.', { timestamp: true })
868880
}
869881

‎packages/vite/src/node/server/ws.ts

+31-33
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { Server } from 'node:http'
2-
import { STATUS_CODES } from 'node:http'
2+
import { STATUS_CODES, createServer as createHttpServer } from 'node:http'
33
import type { ServerOptions as HttpsServerOptions } from 'node:https'
44
import { createServer as createHttpsServer } from 'node:https'
55
import type { Socket } from 'node:net'
66
import colors from 'picocolors'
7-
import type { ServerOptions, WebSocket as WebSocketRaw } from 'ws'
7+
import type { WebSocket as WebSocketRaw } from 'ws'
88
import { WebSocketServer as WebSocketServerRaw } from 'ws'
99
import type { WebSocket as WebSocketTypes } from 'dep-types/ws'
1010
import type { CustomPayload, ErrorPayload, HMRPayload } from 'types/hmrPayload'
@@ -20,6 +20,10 @@ export type WebSocketCustomListener<T> = (
2020
) => void
2121

2222
export interface WebSocketServer {
23+
/**
24+
* Listen on port and host
25+
*/
26+
listen(): void
2327
/**
2428
* Get all connected clients.
2529
*/
@@ -83,7 +87,7 @@ export function createWebSocketServer(
8387
httpsOptions?: HttpsServerOptions,
8488
): WebSocketServer {
8589
let wss: WebSocketServerRaw
86-
let httpsServer: Server | undefined = undefined
90+
let wsHttpServer: Server | undefined = undefined
8791

8892
const hmr = isObject(config.server.hmr) && config.server.hmr
8993
const hmrServer = hmr && hmr.server
@@ -93,6 +97,8 @@ export function createWebSocketServer(
9397
const wsServer = hmrServer || (portsAreCompatible && server)
9498
const customListeners = new Map<string, Set<WebSocketCustomListener<any>>>()
9599
const clientsMap = new WeakMap<WebSocketRaw, WebSocketClient>()
100+
const port = hmrPort || 24678
101+
const host = (hmr && hmr.host) || undefined
96102

97103
if (wsServer) {
98104
wss = new WebSocketServerRaw({ noServer: true })
@@ -104,39 +110,28 @@ export function createWebSocketServer(
104110
}
105111
})
106112
} else {
107-
const websocketServerOptions: ServerOptions = {}
108-
const port = hmrPort || 24678
109-
const host = (hmr && hmr.host) || undefined
110-
if (httpsOptions) {
111-
// if we're serving the middlewares over https, the ws library doesn't support automatically creating an https server, so we need to do it ourselves
112-
// create an inline https server and mount the websocket server to it
113-
httpsServer = createHttpsServer(httpsOptions, (req, res) => {
114-
const statusCode = 426
115-
const body = STATUS_CODES[statusCode]
116-
if (!body)
117-
throw new Error(
118-
`No body text found for the ${statusCode} status code`,
119-
)
113+
// http server request handler keeps the same with
114+
// https://github.com/websockets/ws/blob/45e17acea791d865df6b255a55182e9c42e5877a/lib/websocket-server.js#L88-L96
115+
const route = ((_, res) => {
116+
const statusCode = 426
117+
const body = STATUS_CODES[statusCode]
118+
if (!body)
119+
throw new Error(`No body text found for the ${statusCode} status code`)
120120

121-
res.writeHead(statusCode, {
122-
'Content-Length': body.length,
123-
'Content-Type': 'text/plain',
124-
})
125-
res.end(body)
121+
res.writeHead(statusCode, {
122+
'Content-Length': body.length,
123+
'Content-Type': 'text/plain',
126124
})
127-
128-
httpsServer.listen(port, host)
129-
websocketServerOptions.server = httpsServer
125+
res.end(body)
126+
}) as Parameters<typeof createHttpServer>[1]
127+
if (httpsOptions) {
128+
wsHttpServer = createHttpsServer(httpsOptions, route)
130129
} else {
131-
// we don't need to serve over https, just let ws handle its own server
132-
websocketServerOptions.port = port
133-
if (host) {
134-
websocketServerOptions.host = host
135-
}
130+
wsHttpServer = createHttpServer(route)
136131
}
137-
138132
// vite dev server in middleware mode
139-
wss = new WebSocketServerRaw(websocketServerOptions)
133+
// need to call ws listen manually
134+
wss = new WebSocketServerRaw({ server: wsHttpServer })
140135
}
141136

142137
wss.on('connection', (socket) => {
@@ -210,6 +205,9 @@ export function createWebSocketServer(
210205
let bufferedError: ErrorPayload | null = null
211206

212207
return {
208+
listen: () => {
209+
wsHttpServer?.listen(port, host)
210+
},
213211
on: ((event: string, fn: () => void) => {
214212
if (wsServerEvents.includes(event)) wss.on(event, fn)
215213
else {
@@ -266,8 +264,8 @@ export function createWebSocketServer(
266264
if (err) {
267265
reject(err)
268266
} else {
269-
if (httpsServer) {
270-
httpsServer.close((err) => {
267+
if (wsHttpServer) {
268+
wsHttpServer.close((err) => {
271269
if (err) {
272270
reject(err)
273271
} else {

0 commit comments

Comments
 (0)
Please sign in to comment.