我有一个节点快速/套接字应用程序,其中我的快速服务器进行多次API调用,其中node-rest-client循环遍历var作业中的元素,当每次完成时,它通过套接字io将数据发送到客户端。但是,在大约1000个API调用之后,我偶尔会遇到套接字挂起错误。
events.js:182
throw er; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (_http_client.js:345:15)
at Socket.socketOnEnd (_http_client.js:437:23)
at emitNone (events.js:110:20)
at Socket.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1059:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
您如何处理这些错误?或许我最初尝试编写此函数的代码很糟糕,在这种情况下,有关如何进行多个API调用并将结果发送到所有套接字的任何建议都会连接? (要求,我获取信息的唯一方法是通过进行这些API调用)。
服务器:
setInterval(function(){
var jobs = ['J1', 'J2', 'J3', 'J4'];
var full_data = {};
for(var i = 0; i < jobs.length; i++){
client.get("MY URL", function (data, response) {
io.sockets.emit('progressbar', data);
});
}
console.log(full_data);
}, 5000)
其中,&#39;进度条&#39;是监听数据的客户端功能。
答案 0 :(得分:1)
如果您的jobs
数组变大,那么您可能同时在飞行中有太多请求。它可能是:
我建议使用以下解决方案来处理所有这些问题:
const Promise = require('bluebird');
const utils = require('utils');
client.getAsync = utils.promisify(client.get);
function runJobs() {
var jobs = ['J1', 'J2', 'J3', 'J4'];
var full_data = {};
Promise.map(jobs, function(job) {
return client.getAsync("MY URL").then(data => {
io.emit('progressbar', data);
}).catch(err => {
console.log('something went wrong on the request', err.request.options);
// eat the error on purpose to keep going
});
}, {concurrency: 5}).then(() => {
// All done, process all final data here
// Then, schedule the next iteration
setTimeout(runJobs, 5000);
});
}
runJobs();
一次最多可以运行5个请求(您可以调整该数字),这可以解决上面的第1项和第2项。并且,它使用循环setInterval()
而不是setTimeout()
,因此它不会安排下一次迭代,直到完成前一次迭代(即使目标服务器变得非常慢)。
答案 1 :(得分:0)
结果是导致错误的client.get()请求。这是我的代码来解决这个问题。它仍然是错误,但至少处理错误并且不会导致节点服务器崩溃。如果有更有说服力的处理方式,请告诉我!
setInterval(function(){
var jobs = ['J1', 'J2', 'J3', 'J4'];
var full_data = {};
for(var i = 0; i < jobs.length; i++){
client.get("MY URL", function (data, response) {
io.sockets.emit('progressbar', data);
}).on('error', function (err) {
console.log('something went wrong on the request', err.request.options);
});
}
console.log(full_data);
}, 5000)