【问题标题】:Node stream pipeline stops prematurely节点流管道过早停止
【发布时间】:2022-02-14 11:41:41
【问题描述】:

将这段代码想象成 NAT-ted 服务 (input) 和想要与 input 通信的外部服务 (output) 之间的中继。

此中继位于公共服务器上,并打开两个端口以进行中继:

  • 端口4040 其中input 连接并转发来自目标服务的TCP 流量
  • 端口4041 一些外部客户端连接到中继

中继应该将它从端口4040 上的input 接收到的内容传送到端口4041 上的外部客户端。

我可以看到两个服务都连接到中继,但数据流在之后停止,我怀疑输出套接字正在关闭。在下面的示例中,我使用了stream.pipeline,但我也直接在套接字上尝试了简单的.pipe,结果相同

从“网络”导入网络 从“流”导入流;

export default () => {
    const inputServer = net.createServer();
    const outputServer = net.createServer();

    inputServer.listen(4040, "0.0.0.0", () => {
        console.log('TCP Server is running on port ' + 4040 + '.');
    });

    outputServer.listen(4041, "0.0.0.0", () => {
        console.log('TCP Server is running on port ' + 4041 + '.');
    });

    let inSocket = null;
    inputServer.on('connection', (sock) => {
        inSocket = sock;
    });

    outputServer.on('connection', (sock) => {
        if (inSocket) {
            stream.pipeline(inSocket, sock, (err) => {
                if (err) {
                    console.error('Pipeline failed.', err);
                } else {
                    console.log('Pipeline succeeded.');
                }
            })

            stream.pipeline(sock, inSocket, (err) => {
                if (err) {
                    console.error('Pipeline failed.', err);
                } else {
                    console.log('Pipeline succeeded.');
                }
            })
        }
    });
}

我的目标是为输入服务保持一个开放的套接字,并连接任何输出的继电器。

【问题讨论】:

    标签: node.js sockets stream


    【解决方案1】:

    数据流停止后,我怀疑输出套接字关闭

    pipeline.pipe() 将在输入流结束时自动关闭输出流,因此它不会为连续的输入流连接保持输入流打开。

    使用.pipe(),您可以通过传递一个选项来覆盖该行为:

    inSocket.pipe(sock, {end: false});
    

    sock.pipe(inSocket, {end: false});
    

    然后,您将需要对每个流进行一些单独的错误处理,因为 .pipe() 不像 pipeline() 那样完整的错误处理。

    通过这种方式,您可以让每个流在客户端选择时自行关闭,而不是在给定的流操作完成时让服务器关闭它。

    我没有看到 pipeline() 的类似选项。

    我也很好奇你打算如何使用它。您是否打算有一个长连接inSocket 和多个到 outputServer 的单独连接?您是否打算或一次需要多个 outputServer 连接?或者一次只有一个。由于您不是自动销毁,我想知道当任何套接字断开连接时您是否需要进行一些手动清理(例如,取消管道)? .pipe() 还以不展开所有事件侦听器而闻名,如果您不正确手动清理事件,有时会导致 GC 问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 2019-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多