2016-11-21 41 views
1

使用角帆sailsjs后端通常称为这种方式:手柄连接损失:再进行请求或重新传送响应

this.doSomethingWithItem = function(itemID, callback){ 
     $sails.put('/item/doSomething', {itemID:itemID}). 
     success(function (data, status, headers, config) { 
      callback(data); 
     }). 
     error(function (data, status, headers, config){ 
      alert('Error!'); 
     }); 
    }; 

在后端,大部分的帆(v0.11.0)的控制器函数是相当简单的。一个例子可能看起来像这样:

doSomething: function(req, res) { 
    var p = req.params.all(); 
    postgresClientPool.connect(function(err, client, done) { 
     client.query("SELECT item_do_something_in_this_awesome_function($1) AS dbreturn", [p.itemID], function(err, result) { 
     done(); 
     if(err) { 
      res.status(500).json({success: false}); 
     } 
     else { 
      res.json(result.rows[0].dbreturn[0]); 
     } 
    }); 
    }); 
} 

现在的我们不能影响我们遇到相当频繁而短暂的连接损失(客户端/浏览器和的NodeJS /帆 - 服务器之间)的原因。目前的任务是尽可能地为用户处理这些问题,并避免造成更多不便。

所以,如果正在进行的请求期间的连接中断,逻辑必须是这样的:

  • 检查,如果连接发生中断请求到达服务器之前或之后。
  • 如果它发生在:重新执行请求。
  • 如果事后发生:告诉后端重新发送请求的结果。

现在,该如何实现?

我不知道在每个服务功能中注册$sails.on('disconnect'...是最好的主意。无论如何,我还没有想出如何在函数完成执行后取消注册它们。

+0

您正在使用标准的HTTP选项,并且通过后端进行自动重发响应是不可能的。 我会建议在Angular应用程序中使用一些拦截器,如果您的请求丢失连接,请尝试再次发送它。 不应该太复杂。 –

回答

1

首先,我会建议您将业务逻辑从控制器中分离出来。

您可以检查此其他答案:sails.js access controller method from controller method

通过这样做,你就能够真正再次从控制系统进行调用,而不必做太多。

另外,我们将使用异步模块中的async.retry和async.apply函数。

例如,假设你移动你的代码到一个服务api/services/CustomerService.js例如:

module.exports = { 
    get: function (customerId, done) { 
     // postgresClientPool should be available in a param or globally? 
     // I'd prefer assigning it to the sails object... 
     // and use it like sails.postgresClientPool 
     postgresClientPool.connect(function (err, client, release) { 
      if (err) { 
      release(); 
      done(err); 
      } 
      client.query("SELECT getCustomer($1) AS dbreturn", [customerId], 
      function (err, result) { 
       release(); 
       if (err) { 
       done(err); 
       } else { 
       done(undefined, result.rows[0].dbreturn[0]); 
       } 
      }); 
     }); 
     } 
    }; 

然后,在你的控制,例如,api/controllers/Customer.js

get: function (req, res) { 
    var p = req.params.all(); 
    async.retry(3, async.apply(CustomerService.get, p.customerID), function (err, result) { 
     if (err) { 
     res.status(500).json({ 
      success: false 
     }); 
     } else { 
     res.json(result); 
     } 
    }) 
    } 

如果您需要异步的控制器的顶部。

+0

感谢那些提示!但是,我不太清楚你的答案是否解决了我的实际问题。如果res.json没有到达客户端(浏览器),因为连接丢失 - 异步错误会在这里触发并触发重试?我对此表示怀疑。 – cis