在Vite开发服务器运行ws WebSocket服务器遇WS_ERR_INVALID_CLOSE_CODE错误
在SvelteKit+Vite项目中集成WebSocket服务器时出现无效状态码错误
尝试在Vite内置开发服务器上运行WebSocket服务器,直接通过Vite的httpServer实例让ws监听,出现了无相关记录的致命错误。手动监听httpServer的upgrade事件并调用ws.Server.handleUpgrade(),得到完全相同的错误;去掉handleUpgrade()调用则无错误,问题显然源于该方法。项目基于SvelteKit+TypeScript环境。
相关代码
vite.config.ts
import type { UserConfig } from 'vite'; import { sveltekit } from '@sveltejs/kit/vite'; import { WebSocketServer } from "ws"; const config: UserConfig = { plugins: [ sveltekit(), { name: "webSocketServer", configureServer: (viteDevServer: any) => { const webSocketServer = new WebSocketServer({ server: viteDevServer.httpServer }); } } ] }; export default config;
运行错误日志
执行npm run dev后出现以下错误:
node:events:491 throw er; // Unhandled 'error' event ^ RangeError: Invalid WebSocket frame: invalid status code 16001 at Receiver.controlMessage (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\receiver.js:566:18) at Receiver.getData (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\receiver.js:442:42) at Receiver.startLoop (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\receiver.js:158:22) at Receiver._write (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\receiver.js:84:10) at writeOrBuffer (node:internal/streams/writable:392:12) at _write (node:internal/streams/writable:333:10) at Writable.write (node:internal/streams/writable:337:10) at Socket.socketOnData (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\websocket.js:1274:35) at Socket.emit (node:events:525:35) at addChunk (node:internal/streams/readable:324:12) Emitted 'error' event on WebSocket instance at: at Receiver.receiverOnError (C:\Users\MSJim\Documents\programming-data\visual-studio-code\frontends\sveltekit-websockets-chat\node_modules\ws\lib\websocket.js:1160:13) at Receiver.emit (node:events:513:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { code: 'WS_ERR_INVALID_CLOSE_CODE', [Symbol(status-code)]: 1002 }
错误中的状态码(如16001)每次运行都会随机变化,曾出现过39338、38329、29320等数值。
问题原因
Vite开发服务器本身依赖WebSocket实现热模块替换(HMR),默认路径为/__vite_hmr。当我们直接让ws服务器监听整个httpServer时,会拦截到Vite自身的WebSocket请求,导致ws库解析不符合规范的帧,抛出无效状态码错误。
解决方案
方案1:指定WebSocket自定义路径
创建WebSocketServer时指定path选项,与Vite的HMR路径区分开:
import type { UserConfig } from 'vite'; import { sveltekit } from '@sveltejs/kit/vite'; import { WebSocketServer } from "ws"; const config: UserConfig = { plugins: [ sveltekit(), { name: "webSocketServer", configureServer: (viteDevServer) => { const webSocketServer = new WebSocketServer({ server: viteDevServer.httpServer, path: '/ws' // 自定义WebSocket路径 }); // 处理WebSocket连接逻辑 webSocketServer.on('connection', (ws) => { console.log('客户端已连接'); ws.on('message', (data) => { console.log('收到消息:', data.toString()); }); }); } } ] }; export default config;
前端连接时需对应使用路径:ws://localhost:5173/ws
方案2:过滤Vite的HMR请求
通过手动处理upgrade事件,只处理非Vite HMR的WebSocket请求:
import type { UserConfig } from 'vite'; import { sveltekit } from '@sveltejs/kit/vite'; import { WebSocketServer } from "ws"; const config: UserConfig = { plugins: [ sveltekit(), { name: "webSocketServer", configureServer: (viteDevServer) => { const wss = new WebSocketServer({ noServer: true }); viteDevServer.httpServer.on('upgrade', (request, socket, head) => { // 跳过Vite HMR的请求 if (request.url?.startsWith('/__vite_hmr')) { return; } // 处理自定义WebSocket请求 wss.handleUpgrade(request, socket, head, (ws) => { wss.emit('connection', ws, request); }); }); // 处理WebSocket连接逻辑 wss.on('connection', (ws) => { console.log('客户端已连接'); ws.on('message', (data) => { console.log('收到消息:', data.toString()); }); }); } } ] }; export default config;
内容的提问来源于stack exchange,提问作者OOPS Studio
相关产品推荐
相关产品推荐

