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

res.write()在socket.on方法内无法正常工作的问题排查

问题:Express SSE接口res.write无输出,但服务器日志正常打印

我编写了如下Express路由代码,当请求命中/optimizationStatus接口时,会通过socket.emit发送payload数据到optimization事件,但遇到了问题:

router.get('/optimizationStatus', (req, res) => {
    console.log('test');

    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
    });
    let data = {
        .. some Data
    };
    socket.emit('optimization', data);
    socket.on('message', (data) => {
        console.log('MESSAGE', data);
        res.write(`data: ${JSON.stringify(data)}

`);
    });
    req.on('close', () => {
        socket.off('optimization');
    });
});

问题表现:socket.on('message')回调内的console.log('MESSAGE', data)能正常打印数据,但res.write无法向客户端输出内容。用Postman测试时,请求一直处于加载状态,但服务器端能看到日志输出。


解决方法

1. 手动调用res.flush()发送缓冲区数据

Express的res.write不会自动刷新输出缓冲区,数据会暂存在内存中,客户端无法接收。需要在每次res.write后调用res.flush()(Express 4.16+版本支持):

socket.on('message', (data) => {
    console.log('MESSAGE', data);
    res.write(`data: ${JSON.stringify(data)}\n\n`);
    res.flush(); // 强制发送缓冲区数据到客户端
});

2. 修复事件监听的移除逻辑

当前req.close回调里移除的是optimization事件监听,但实际绑定的是message事件,这会导致内存泄漏。应该先把回调函数存为变量,再精准移除:

// 提取回调函数为变量
const messageHandler = (data) => {
    console.log('MESSAGE', data);
    res.write(`data: ${JSON.stringify(data)}\n\n`);
    res.flush();
};
socket.on('message', messageHandler);

req.on('close', () => {
    socket.off('message', messageHandler); // 移除对应的message监听
});

3. 发送初始确认消息

部分客户端(包括Postman)需要先收到一条合法的SSE消息才会开始展示内容。可以在路由初始化时先发送一条连接确认消息:

res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
});
// 发送初始连接确认
res.write('data: {"status": "connected"}\n\n');
res.flush();

4. 确保SSE消息格式正确

SSE要求每条消息必须以\n\n结尾,建议直接使用转义字符而非模板字符串换行,避免格式错误:

// 用\n\n替代模板字符串中的换行
res.write(`data: ${JSON.stringify(data)}\n\n`);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:07:16