使用sockets.io超出了node.js调用堆栈
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用sockets.io超出了node.js调用堆栈相关的知识,希望对你有一定的参考价值。
我正在做一个项目,我必须继续轮询网络(本地网络)上的许多设备的状态,然后在socket.io连接上向客户端发送此状态。
当设备连接良好时,我可以启动并运行代码,但是如果其中一个从网络中掉落,我得到:
RangeError: Maximum call stack size exceeded
at Function.isBuffer (buffer.js:398:36)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:42:87)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
at hasBinary (c:ProjectsActiveAL10-2.0al10-server_sqlite
ode_moduleshas-binary2index.js:56:59)
我的代码看起来像这样:
var express = require("express");
var app = express();
var http = require("http").Server(app);
var Client = require("node-rest-client").Client;
var rest = new Client();
var io = require("socket.io")(http);
var sqlite3 = require("sqlite3");
function test(counter=0, list=[]){
// console.log(counter);
if(list.length == 0 || counter >= list.length){
var query = "SELECT url FROM paths";
db.all(query, (err,data) => {
if(err){
throw (err);
}
test(0, data);
});
}
else{
setTimeout( () => {
GetStatus(list[counter].url, (err, restData) => {
if(err){
/* As soon as one of these are added,
the callstack is exceeded */
// setTimeout(io.sockets.emit("error", err),50);
// io.sockets.emit("error", err);
console.log(err);
}
else{
/* This one is no problem */
io.sockets.emit("status", restData);
console.log(counter + " - " + restData.HeartBeat);
}
// process.nextTick(test, ++counter, list);
test(++counter, list);
});
},1000);
}
}
function GetStatus(url, callback){
var req = rest.get(url, ((data,response) => {
if(response.statusCode == 200){
callback(null,data);
}
else{
callback(response.statusCode,null);
}
}).bind(this));
req.on("error",(function(err){
/* All of the following yeilds the same result */
callback(err,null);
// process.nextTick(callback,err,null);
// setTimeout(callback(err,null),0);
}).bind(this));
}
var db = new sqlite3.Database(":memory:", (err) => {
if(err) return;
});
db.serialize(() => {
var values = ["http://192.168.42.69/restapi/status","http://192.168.42.70/restapi/status"];
db.run("CREATE TABLE paths(url text)")
.run("INSERT INTO paths(url) VALUES (?),(?)", values, (err) => {
if(err){
throw err;
}
test();
});
});
当我添加io.sockets.emit("error",err);
(有或没有setTimeout(...)
)代码失败并给我RangeError。
上面的代码是一个孤立的测试,试图弄清楚它为什么不起作用。在实际应用中,还有一些网址,它们可能会随着时间的推移而改变。在实际应用程序中,此例程还将不时地在数据库中查询URL中的更改...
我试图在this post中实现一些答案,但无济于事。
所以我的问题是,为什么socket.io调用会给我的堆栈溢出?而且,我如何让它工作?
我在用
node.js - 8.9.4
socket.io - 2.0.3
sqlite3 - 3.1.13
node-rest-client - 3.1.0
express - 4.15.3
我刚想通了。
This帖子有同样的错误,修复也在这里工作。
问题是来自err
的其余调用的GetStatus(list[counter].url, (err, restData) => {...})
对象。当发送它时,err
对象是自引用的并且导致调用堆栈被泛洪。
将其更改为非自引用对象使其即使没有setTimeout()
也能正常工作
以上是关于使用sockets.io超出了node.js调用堆栈的主要内容,如果未能解决你的问题,请参考以下文章
Node.js + Socket.io 超出最大调用堆栈大小
到底是用 Ajax 还是 Socket.IO? 用测试数据说话!
在 android 上解析 socket.io 数据。 (Gottox Socket.IO)
在 node.js 中使用 createWriteStream 创建大文件时 JavaScript 堆内存不足致命错误:达到堆限制分配失败