Nodejs 求助res.writeHead加入Connection: keep-alive的方法

Nodejs 求助res.writeHead加入Connection: keep-alive的方法

最近想在node.js上面模拟Transfer-Encoding:chucked时的发包。无奈不加上Connection:keep-alive本地怎么也接收不了完整的数据报。无奈只好尝试在writeHead上面加上这个协议头,不过问题是Vary,Transfer-Encoding,Cookie之类的协议头都发出去了,而这个协议头貌似被无视了。不知道跟express有无关系,还是node.js本身就不能设置这个协议头。因为我只有一个部分要使用到这样的流式传输,别的部分我要用express的res.send来发包,所以不能离开express。所以希望大家能帮我想一个不舍弃使用express也能实现这个功能的办法。

代码在下面:

exports.action = function (req, res) {
        res.writeHead(200, {
            'Content-Type': 'text/xml;charset=ISO-8859-1',
            'Transfer-Encoding': 'chunked',
            'Vary': 'Accept-Encoding',
            'Set-Cookie': 'test=1;',
            'Connection': 'keep-alive'}); //最后一行怎么加都没用 用express的set也不行
    res.write(respondData(SoapSign,ParseData(SoapBody[0]))); 
    res.end();

};

在此先感谢回复的大神们


6 回复

当然可以!根据你的描述,你希望在 Node.js 中使用 Express 来发送带有 Connection: keep-alive 的响应,并且能够支持 Transfer-Encoding: chunked。以下是解决这个问题的一个方法。

解决方案

在 Express 中直接设置 Connection: keep-alive 可能不会生效,因为 Express 会自动管理连接。但你可以通过手动控制 HTTP 响应头来实现这一目标。以下是一个示例代码,展示了如何实现这一点:

const express = require('express');
const app = express();

app.get('/your-endpoint', (req, res) => {
    res.setHeader('Connection', 'keep-alive'); // 设置 Connection 头
    res.setHeader('Content-Type', 'text/xml;charset=ISO-8859-1');
    res.setHeader('Transfer-Encoding', 'chunked');
    res.setHeader('Vary', 'Accept-Encoding');
    res.setHeader('Set-Cookie', 'test=1;');

    // 开始发送数据
    res.write(respondData(SoapSign, ParseData(SoapBody[0])));
    
    // 结束响应
    setTimeout(() => {
        res.end();
    }, 1000); // 模拟延迟发送数据
});

function respondData(sign, data) {
    return `${data.length}\r\n${data}\r\n`; // 示例数据格式
}

// 模拟 SoapSign 和 SoapBody
const SoapSign = 'example-sign';
const SoapBody = ['example-data'];

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 设置响应头

    • 使用 res.setHeader 方法来设置 Connection: keep-aliveContent-TypeTransfer-EncodingVarySet-Cookie
    • 注意,Connection: keep-alive 是必需的,以确保客户端保持连接。
  2. 发送数据

    • 使用 res.write 方法发送数据块。这里使用了一个简单的 respondData 函数来生成数据块。
    • 在实际应用中,你可能需要根据具体需求调整数据的生成逻辑。
  3. 结束响应

    • 使用 res.end 方法结束响应。这里添加了一个 setTimeout 来模拟延迟发送数据。

注意事项

  • Transfer-Encoding: chunked 需要配合 res.writeres.end 使用,确保数据以分块的方式发送。
  • Connection: keep-alive 确保客户端保持连接,以便接收所有数据块。

这样,你就可以在不放弃使用 Express 的情况下,实现所需的流式传输功能。希望这能解决你的问题!


这个情况不是很清楚,不过express也是一个静态服务器呀,可以断点续传吧。你具体要模拟什么?

模拟流式传输。现在就差加上Connection:kepp-alive这个协议头就好了。没这个客户端会自动忽视接下来接收的数据包。就是不知道怎样才能加上去

默认就是有的啊

抓包看了是沒有的

在Node.js中,如果你使用Express框架,直接在res.writeHead中添加Connection: keep-alive可能会被Express忽略或覆盖。这是因为Express有一些默认的行为,可能会影响HTTP头部的设置。

为了在保持使用Express的同时能够实现Connection: keep-alive,你可以通过设置Express应用实例来达到目的。具体来说,可以在创建Express应用实例之后,使用app.set('etag', false)等方法来禁用某些默认行为,并确保HTTP头部可以按预期设置。

以下是具体的修改方式:

const express = require('express');
const app = express();

// 禁用ETag以避免Express覆盖自定义的HTTP头部
app.set('etag', false);

app.get('/your-endpoint', function (req, res) {
    res.setHeader('Transfer-Encoding', 'chunked');
    res.setHeader('Vary', 'Accept-Encoding');
    res.setHeader('Set-Cookie', 'test=1;');
    res.setHeader('Connection', 'keep-alive');

    res.write(respondData(SoapSign, ParseData(SoapBody[0])));
    res.end();
});

function respondData(sign, data) {
    // 假设这是你的数据处理逻辑
    return data;
}

app.listen(3000, () => console.log('Server running on port 3000'));

在这个例子中,我们通过res.setHeader方法显式地设置了HTTP头部。同时,我们还通过app.set('etag', false)禁用了ETag,这有助于防止Express覆盖你自定义的头部。

请注意,这里的respondData函数需要根据你的实际业务逻辑进行实现。希望这个解决方案对你有所帮助!

回到顶部