You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:44