【问题标题】:Nodejs error handling with domains and socket.io使用域和 socket.io 处理 Nodejs 错误
【发布时间】:2013-04-16 23:33:14
【问题描述】:

我刚刚开始在 nodejs 中使用域进行错误管理。

当我将它们与 socket.io 一起使用时,有些东西我无法理解。

这是我的示例代码:

io.sockets.on('connection', function cb1(socket){
    socket.on('event', function cb2(data){
    });
});

我开始将所有代码放入“运行”方法中

domain.run(function(){
    io.sockets.on('connection', function cb1(socket){
        socket.on('event', function cb2(data){
        });
    });
});

但如果 cb1 或 cb2 发生错误,则不予处理!

然后我在 che cb1 上使用了绑定方法

domain.run(function(){
    io.sockets.on('connection', domain.bind(function cb1(socket){
        socket.on('event', function cb2(data){
        });
    }));
});

但是如果在 cb2 中发生错误,它不会被处理!

我的问题是: 我必须在每个回调上放置一个“绑定”吗?在服务器和所需文件中?

当我开始研究这些领域时,所有教程都将它们定义为一站式处理错误的最佳解决方案!

我错过了什么吗?

【问题讨论】:

  • 所有答案都没有帮助吗?

标签: node.js socket.io dns node.js-domains


【解决方案1】:

如果您在域范围内创建套接字,则该套接字对象中引发错误的所有事件都将被域捕获。

domain.run(function(){
  var io = require('socket.io').listen(80);
  io.sockets.on('connection', function cb1(socket){
    socket.on('event', function cb2(data){
   });
  }));
});

试试这个。

【讨论】:

    【解决方案2】:

    (我是dorexx45,忘记密码了)

    我试过了,但它部分有效。

    如果我在域内创建一个对象(例如 mysql 连接),则不会处理该对象上的错误!

    domain.run(function(){
      var pool = mysql.createPool();
      var io = require('socket.io').listen(80);
      io.sockets.on('connection', function cb1(socket){
        socket.on('event', function cb2(data){
           pool.something();
       });
      }));
    });
    

    如果pool.something() 中发生某些事情,例如错误的查询语法或错误的连接数据,domain.run 不会“捕获”该错误!

    【讨论】:

    • 如果我只是把 n 显式抛出它会发生同样的情况。如果我在 cb1 中抛出错误,它将被缓存,如果我在 cb2 中抛出错误,则不是!
    • 您忘记了密码@dorexx45?这意味着您将无法将任何答案标记为正确答案?史诗大笑:)
    【解决方案3】:

    编辑:是的,你必须绑定每个回调。

    看看这个截屏视频,它解释了这个问题:Node Tuts Episode VIII - Handling Errors Using Domains(他从 13:45 开始谈论这个)。

    如果我理解正确,如果你没有在回调中发出或抛出错误,你必须用.bind.intercept 显式绑定它们。但根据我自己在回调方面的经验,这还不够,我必须将每个回调绑定到域。

    【讨论】:

      【解决方案4】:

      我所做的是为每个套接字创建一个新域:

      var Domain = require('domain');
      
      ...
      
      io.sockets.on('connection', function (socket){
      
          d = domain.create();
          d.add(socket);
      
          d.on('error', function () {
      
              // You have access to the socket too in here, useful
          });
      
          socket.on('event', function (data){
      
              socket.on('event2', function (data){
      
                  throw new Error('I will be caught!');
              });
          });
      });
      

      为什么会这样?

      Domain.prototype.add 会将现有的事件发射器添加到域中。这意味着该发射器上事件的所有新回调都将隐式绑定到域。

      【讨论】:

        猜你喜欢
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 2021-01-21
        • 2017-10-13
        • 1970-01-01
        • 2013-07-18
        • 1970-01-01
        • 2018-09-21
        相关资源
        最近更新 更多