我在Heroku上有一个ZombieJS节点服务器从互联网上删除数据。从客户端的for
循环调用服务器代码。循环的每次迭代都会产生一个服务器调用,这使得Zombie刮擦。有时,服务器会因以下错误而崩溃。它只发生在for
循环的多次迭代时。
如何使代码足够健壮以处理多个同时进行的客户端调用,每个调用都有一个for
循环。
代码:
var express = require('express');
var app = express();
var Browser = require('zombie'); // tried changing var to const; no difference
var assert = require('assert');
app.set('port', (process.env.PORT || 5000));
var printMessage = function() { console.log("Node app running on " + app.get('port')); };
var getAbc = function(response, input)
{
var browser = new Browser();
browser.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0';
browser.runScripts = true;
var url = "http://www.google.com/ncr";
browser.visit(url, function() {
browser.fill('q', input).pressButton('Google Search', function(){
// parsing number of results from browser object
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(numberOfSearchResults);
});
});
}
var handleXyz = function(request, response)
{
getAbc(response, request.query.input);
}
app.listen(app.get('port'), printMessage);
app.post('/xyz', handleXyz);
错误:
assert.js:86
throw new assert.AssertionError({
^
No open window with an HTML document
at Browser.field (/app/node_modules/zombie/lib/index.js:811:7)
at Browser.fill (/app/node_modules/zombie/lib/index.js:903:24)
at /app/cfv1.js:42:11
at done (/app/node_modules/zombie/lib/eventloop.js:589:9)
at timeout (/app/node_modules/zombie/lib/eventloop.js:594:33)
at Timer.listOnTimeout (timers.js:119:15)
我有一个使用HorsemanJS / PhantomJS的类似项目,它以类似的方式失败了(我也坚持了!):NodeJS server can't handle multiple users
答案 0 :(得分:1)
一般来说,我认为您应该小心,或者只是避免向远程服务器生成大量未经请求的请求。许多网站会限制您和/或开始拒绝连接。话虽如此,我相信在这种特殊情况下我找到了问题的根源。
我测试了代码段,对于这种特殊情况,如果您发出太多请求,Google会重置连接。重置连接后,其中一个变量最终会失败。
重置连接时出现的错误:
zombie TypeError: read ECONNRESET
at zombie/lib/pipeline.js:89:15
at tryCatcher (zombie/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (zombie/node_modules/bluebird/js/release/promise.js:497:31)
at Promise._settlePromise (zombie/node_modules/bluebird/js/release/promise.js:555:18)
at Promise._settlePromise0 (zombie/node_modules/bluebird/js/release/promise.js:600:10)
at Promise._settlePromises (zombie/node_modules/bluebird/js/release/promise.js:679:18)
at Async._drainQueue (zombie/node_modules/bluebird/js/release/async.js:125:16)
at Async._drainQueues (zombie/node_modules/bluebird/js/release/async.js:135:10)
at Immediate.Async.drainQueues [as _onImmediate] (zombie/node_modules/bluebird/js/release/async.js:16:14)
at processImmediate [as _immediateCallback] (timers.js:383:17)
我将原始错误进一步降低,但问题的根源实际上是因为上述原因。当发生上述情况时,它会导致document.documentElement为false-y值,并随后导致字段函数中zombie / lib / index.js中的此断言失败:
assert(this.document && this.document.documentElement, 'No open window with an HTML document');
我认为最简单的解决方案是在客户端处理错误并尝试优雅地恢复。
答案 1 :(得分:0)
我看到你正在为每个调用创建一个Browser对象的新实例。我的猜测是以前的#34;浏览器"当下一个呼叫试图打开另一个呼叫时,垃圾收集器仍处于关闭状态,或者尚未处理。尝试将浏览器的实例化移动到getAbc()
之外