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

无法访问底层HTTP服务器时,如何在Express中间件中实现WebSocket升级?

在Express中间件中处理WebSocket升级(无法访问底层HTTP服务器)

背景需求

我正在编写一个Express中间件,需要处理多个端点——大部分是纯HTTP端点,少数特殊端点需要通过WebSocket实现双向通信。

常规实现(可访问底层HTTP服务器时)

当能直接操作底层HTTP服务器时,标准实现可以正常工作:

import http from 'http';
const server = http.createServer(app);
app.listen = function serverListen(...args) {
    return server.listen(...args);
};
const wss = new WebSocketServer({ server: server });
wss.on('connection', (ws) => {
    ws.on('message', (message) => {
        console.log('Received:', message);
        ws.send('Message received: ' + message);
    });
});
server.on('upgrade', function upgrade(request, socket, head) {
    wss.handleUpgrade(request, socket, head, function done(ws) {
        wss.emit('connection', ws, request);
    });
});

这里HTTP服务器触发的upgrade事件提供的request、socket和head三个参数,是正确调用wss.handleUpgrade的关键。

当前问题

我无法访问底层HTTP服务器,也找不到从Express中间件的req、res对象中直接提取这三个参数的方法(包括express-ws这类库也依赖底层HTTP服务器实例)。

目前我已经从Express的req对象中拿到了request和req.socket,但缺少head参数:

wss.handleUpgrade(req, req.socket, ???, (websocket) => {
    wss.emit('connection', websocket, req);
});

尝试的方案及报错

我尝试手动构造head参数,代码如下:

if (path === '/transaction/.websocket') {
    console.log('Transaction request');

    // 校验是否为WebSocket升级请求
    if (!req.headers.upgrade || req.headers.upgrade.toLowerCase() !== 'websocket') {
        return res.status(400).send('Invalid WebSocket upgrade request');
    }

    // 获取Sec-WebSocket-Key请求头
    const secWebSocketKey = req.headers['sec-websocket-key'];
    if (!secWebSocketKey) {
        return res.status(400).send('Missing Sec-WebSocket-Key header');
    }

    // 计算Sec-WebSocket-Accept值
    const secWebSocketAccept = crypto
        .createHash('sha1')
        .update(secWebSocketKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11=')
        .digest('base64');

    // 构造head缓冲区
    const head = Buffer.from(
        `HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ${secWebSocketAccept}\r\n\r\n`,
    );
    
    // 执行WebSocket升级处理
    wss.handleUpgrade(req, req.socket, head, (websocket) => {
        wss.emit('connection', websocket, req);
    });
    
}

但运行时服务器抛出错误:Uncaught RangeError: Invalid WebSocket frame: RSV1 must be clear。


内容的提问来源于stack exchange,提问作者Eliav Louski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:24:52