NodeJS CouchDB长轮询崩溃

当然,我有一个通过NodeJS上的ExpressJS发布的web应用程序。 它使用CouchDB作为数据源。 我实现了长轮询以保持应用程序在所有用户之间始终保持同步。 要做到这一点,我使用以下逻辑:

  1. 用户login到应用程序,并通过Express路线向Node发起初始的长轮询请求。
  2. 节点轮stream向CouchDB发出长轮询请求。
  3. 当Couch更新时,它响应来自Node的请求。
  4. 最后Node响应浏览器。

简单。 但是,发生的事情是,当我刷新浏览器时, 每五次刷新就会冻结一次 。 咦? 非常奇怪。 但是,即使在我的testing环境中,我也可以一遍又一遍地重现它。 每五次刷新一次,冻结Node并导致应用程序冻结。 重启节点解决了这个问题。

拉了很多头发后,我想通过改变这个问题来解决它:

app.get('/_changes/:since*', security, routes.changes); 

对此:

 app.get('/_changes/:since*', security, function () { routes.changes }); 

然而,经过进一步的testing,这只是没有运行routes.changes。 所以没有实际解决scheme 任何想法为什么长期投票CouchDb从Node会做这样一个奇怪的事情? 在第五次刷新,我可以在我的路由代码的第一行节点中有一个断点,它永远不会被击中。 但是,在浏览器中,我可以断开对长时间轮询的节点的请求,并且它似乎熄灭。 这就像Node由于某种原因不接受连接

我应该以不同的方式接近从Node到CouchDB的长轮询吗? 我正在使用feed = longpoll,我应该做feed还是连续的? 如果我将couchdb中的changes_timeout调低到5秒,它就不能解决问题,但是它可以更容易地处理,因为冻结只会持续5秒钟。 所以这似乎表明节点不能处理有几个待处理的请求。 也许我会尝试一个连续的饲料,看看会发生什么。

self.getChanges = function(since){

浏览器:

  $.ajax({ url: "/_changes/" + since, type: "GET", dataType: "json", cache: false, success: function (data) { try { self.processChanges(data.results); self.lastSeq(data.last_seq); self.getChanges(self.lastSeq()); self.longPollErrorCount(0); } catch (e) { self.longPollErrorCount(self.longPollErrorCount() + 1); if (self.longPollErrorCount() < 10) { setTimeout(function () { self.getChanges(self.lastSeq()); }, 3000); } else { alert("You have lost contact with the server. Please refresh your browser."); } } }, error: function (data) { self.longPollErrorCount(self.longPollErrorCount() + 1); if (self.longPollErrorCount() < 10) { setTimeout(function () { self.getChanges(self.lastSeq()); }, 3000); } else { alert("You have lost contact with the server. Please refresh your browser."); } } }); } 

节点:

路由:

 exports.changes = function (req, res) { var args = {}; args.since = req.params.since; db.changes(args, function (err, body, headers) { if (err) { console.log("Error retrieving changes feed: "+err); res.send(err.status_code); } else { //send my response... code removed here } }) } 

数据库长时间查询调用

 self.changes = function (args, callback) { console.log("changes"); if (args.since == 0) { request(self.url + '/work_orders/_changes?descending=true&limit=1', function (err, res, headers) { var body = JSON.parse(res.body); var since = body.last_seq; console.log("Since change: "+since); self.longPoll(since, callback); }); } else { self.longPoll(args.since, callback); } } self.longPoll = function (since, callback) { console.log("about to request with: "+since); request(self.url + '/work_orders/_changes?feed=continuous&include_docs=true&since=' + since, function (err, res, headers) { console.log("finished request.") if (err) { console.log("Error starting long poll: "+err.reason); return; } //if err send it back callback(err, res.body); }); } 

Socket.io将自动回退到长轮询,并没有像你正在遇到的问题。 所以就用那个吧 此外,对于CouchDB的变化使用此https://github.com/iriscouch/follow或者这一个https://npmjs.org/package/changes像其他人build议&#x3002;

当我们有stream行的模块,已经做你所需要的,它是非常糟糕的做法重塑事情。 https://npmjs.org/目前有超过52,000个节点模块&#x3002; 人们对复制和粘贴代码做了大量的工作。 在我看来,重新创build基本的东西比这更糟糕。

我知道有这么多模块很难知道他们,所以我并不是说你永远不可能像别人一样解决同样的问题。 但首先看看npmjs.org,还有像http://node-modules.com/这样的网站可能会给出更好的search结果&#x3002;