繁体   English   中英

节点 stream 管道过早停止

[英]Node stream pipeline stops prematurely

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

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

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

中继应该 pipe 它从端口4040上的input接收到端口4041上的外部客户端。

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

import.net from .net" 从 "stream" 导入 stream;

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.');
                }
            })
        }
    });
}

我的目标是保持输入服务和中继的开放套接字,任何 output 都将连接。

之后数据流就停止了,我怀疑 output 套接字正在关闭

当输入 stream 结束时, pipeline.pipe()将自动关闭 output stream,因此它不会让您的输入 stream 打开连续输入 stream 连接。

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM