【问题标题】:Node.js header error after TCP connection lostTCP连接丢失后的Node.js标头错误
【发布时间】:2016-04-10 19:57:26
【问题描述】:

我是Node.js 的新手,我正在使用this library 连接到CasparCG server(TCP 连接)。现在,我正在尝试创建某种类型的错误处理,我有一个两部分的问题。

我连接正常,我的 UI 显示连接已建立。然后出于测试目的,我重新启动服务器导致连接丢失。我在控制台中收到此消息:

_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
      ^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (C:\www\node-    test\node_modules\express\lib\response.js:718:10)
at ServerResponse.send (C:\www\node-test\node_modules\express\lib\response.js:163:12)
at ServerResponse.json (C:\www\node-test\node_modules\express\lib\response.js:249:15)
at null.<anonymous> (C:\www\node-test\api\caspar.js:33:44)
at emit (events.js:104:17)
at Socket.<anonymous> (C:\www\node-test\node_modules\caspar-cg\lib\connection.js:60:9)
at Socket.emit (events.js:129:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:991:10)
Program node server.js exited with code 1

路线:

var CasparCG = require('caspar-cg');
var ccg = new CasparCG("192.168.1.100", 5250);

var _cg_connected = false;

ccg.on('connected', function () {
    _cg_connected = true;
});

ccg.on('error', function (error) {
    _cg_connected = false;
    console.log(error);
});

ccg.on('connectionError', function (error) {
    _cg_connected = false;
    console.log(error);
});

ccg.on('end', function () {
    _cg_connected = false;
    console.log('Connection ended');
});

ccg.on('close', function () {
    _cg_connected = false;
    console.log('Connection closed');
});

module.exports = function(router, connection) {
router.post('/casparcg/connect', function(req, res) {
    if(_cg_connected) {
        return res.status(200).json({success: true, message: 'Connection already established'});
    }

    ccg.connect(function () {
         if(_cg_connected) {
            return res.status(200).json({success: true, message: 'Connection established'});
        } else {
            return res.status(503).json({success: false, message: 'Connection failed'});
        }
    });
});

}

现在我如何才能真正捕获此“连接丢失”错误或其他导致崩溃并重新启动的错误?

我的第二个问题:

我的应用程序使用 node.js 作为 AngularJS 前面的 REST API。我可以为 AngularJS 创建某种类型的侦听器,它捕获 node.js 发送消息“我们已经失去连接。让你知道”并且 AngularJS 可以在这种情况下适当地适应这意味着我可以关闭变量 connection = false 并设置按钮相应地。

编辑:

发现代码中的错误。将所有 TCP 'on' 监听器移到路由之外,只留下 connect(callback) 那里。它现在会在重新启动时自动重新连接,但会在完全断开连接时记录错误。

【问题讨论】:

    标签: angularjs node.js sockets tcp


    【解决方案1】:

    您的代码执行以下操作:

    • 处理对/casparcg/connect的POST请求
    • 在您的处理程序中,您正在建立一个新连接并对随着时间的推移可能发生的各种事件做出反应(可能在初始请求后几分钟)
    • 但一个 HTTP 请求只能回答一次
    • 当您的代码运行初始 connect 事件时,它将使用 200 状态码回复 POST 请求
    • 稍后,当收到事件(如错误)时,它会尝试再次回复相同的请求...这将不起作用,因为“标头已发送”(即客户早已不在)。

    所以问题是逻辑问题之一。您正在尝试建立一个长时间运行的请求(以检测断开连接),但您在建立连接时回答该请求......您无法改变主意并稍后发送“oops disconnected”,因为回复已经发送了。

    另外,建立一个新连接只是为了检测该连接的断开可能是个坏主意……我猜你的应用需要另一个连接来做真正的事情。

    如果你真的需要“会话/连接设计”,那么切换到 WebSockets,ajax/REST 不会解决它。 Websockets 允许一个有状态的设计,其中建立了连接,可以在双方进行监控,并且可以在客户端和服务器之间以任何顺序发送任意数量的消息。 如果你不想使用 websockets,你最终还是会实现一个穷人的 websockets...

    我也不知道ccg 是什么,但看起来你连接到它时没有参数......所以连接并不真正依赖于连接的用户......也许你可以建立一个单一的所有用户的连接?或者可能使用n 连接池为N 客户端提供服务,其中n &lt; N... 并避免浪费连接和连接延迟...

    【讨论】:

    • 你是对的。我实际上调整了将 .on() 函数移到路由之外的代码,因为它们不需要“重新建立”。连接路由现在只尝试连接,如果它已经连接,则返回 true。它现在在重新启动时重新连接,并且在我关闭服务器时不会崩溃。它记录了一个超时,但我可以以某种方式捕获它并将其发送到 Angular 吗?
    • 好的,谢谢!这实际上是解决方案。我已经开始工作了。
    猜你喜欢
    • 2018-03-09
    • 2017-09-08
    • 2014-01-26
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    相关资源
    最近更新 更多