Я просто вызываю «ìo.sockets.emit (« эй », данные); and it will crash with
RangeError: Превышен максимальный размер стека вызовов . I use it in other places in my app and it works fine. I am not repeating this (checked with console). The logs say the error is in
socket.io/node_modules/has-binary-data/index.js: 46 ''.
Не знаю, в чем проблема. Я пробовал регистрировать io.sockets
прямо перед его использованием, и он выводит следующее:
{ name: '/',
17:39:37 web.1 | server:
17:39:37 web.1 | { nsps: { '/': [Circular] },
17:39:37 web.1 | _path: '/socket.io',
17:39:37 web.1 | _serveClient: true,
17:39:37 web.1 | _adapter: [Function: Adapter],
17:39:37 web.1 | _origins: '*:*',
17:39:37 web.1 | sockets: [Circular],
17:39:37 web.1 | eio:
17:39:37 web.1 | { clients: [Object],
17:39:37 web.1 | clientsCount: 2,
17:39:37 web.1 | pingTimeout: 60000,
17:39:37 web.1 | pingInterval: 25000,
17:39:37 web.1 | upgradeTimeout: 10000,
17:39:37 web.1 | maxHttpBufferSize: 100000000,
17:39:37 web.1 | transports: [Object],
17:39:37 web.1 | allowUpgrades: true,
17:39:37 web.1 | allowRequest: [Function],
17:39:37 web.1 | cookie: 'io',
17:39:37 web.1 | ws: [Object],
17:39:37 web.1 | _events: [Object] },
17:39:37 web.1 | engine:
17:39:37 web.1 | { clients: [Object],
17:39:37 web.1 | clientsCount: 2,
17:39:37 web.1 | pingTimeout: 60000,
17:39:37 web.1 | pingInterval: 25000,
17:39:37 web.1 | upgradeTimeout: 10000,
17:39:37 web.1 | maxHttpBufferSize: 100000000,
17:39:37 web.1 | transports: [Object],
17:39:37 web.1 | allowUpgrades: true,
17:39:37 web.1 | allowRequest: [Function],
17:39:37 web.1 | cookie: 'io',
17:39:37 web.1 | ws: [Object],
17:39:37 web.1 | _events: [Object] } },
17:39:37 web.1 | sockets:
17:39:37 web.1 | [ { nsp: [Circular],
17:39:37 web.1 | server: [Object],
17:39:37 web.1 | adapter: [Object],
17:39:37 web.1 | id: 'RfgXeMgHeP_9SQC5AAAC',
17:39:37 web.1 | client: [Object],
17:39:37 web.1 | conn: [Object],
17:39:37 web.1 | rooms: [Object],
17:39:37 web.1 | acks: {},
17:39:37 web.1 | connected: true,
17:39:37 web.1 | disconnected: false,
17:39:37 web.1 | handshake: [Object],
17:39:37 web.1 | _events: [Object] },
17:39:37 web.1 | { nsp: [Circular],
17:39:37 web.1 | server: [Object],
17:39:37 web.1 | adapter: [Object],
17:39:37 web.1 | id: '7TEjGJjWzxObulClAAAD',
17:39:37 web.1 | client: [Object],
17:39:37 web.1 | conn: [Object],
17:39:37 web.1 | rooms: [Object],
17:39:37 web.1 | acks: {},
17:39:37 web.1 | connected: true,
17:39:37 web.1 | disconnected: false,
17:39:37 web.1 | handshake: [Object],
17:39:37 web.1 | _events: [Object] } ],
17:39:37 web.1 | connected:
17:39:37 web.1 | { RfgXeMgHeP_9SQC5AAAC:
17:39:37 web.1 | { nsp: [Circular],
17:39:37 web.1 | server: [Object],
17:39:37 web.1 | adapter: [Object],
17:39:37 web.1 | id: 'RfgXeMgHeP_9SQC5AAAC',
17:39:37 web.1 | client: [Object],
17:39:37 web.1 | conn: [Object],
17:39:37 web.1 | rooms: [Object],
17:39:37 web.1 | acks: {},
17:39:37 web.1 | connected: true,
17:39:37 web.1 | disconnected: false,
17:39:37 web.1 | handshake: [Object],
17:39:37 web.1 | _events: [Object] },
17:39:37 web.1 | '7TEjGJjWzxObulClAAAD':
17:39:37 web.1 | { nsp: [Circular],
17:39:37 web.1 | server: [Object],
17:39:37 web.1 | adapter: [Object],
17:39:37 web.1 | id: '7TEjGJjWzxObulClAAAD',
17:39:37 web.1 | client: [Object],
17:39:37 web.1 | conn: [Object],
17:39:37 web.1 | rooms: [Object],
17:39:37 web.1 | acks: {},
17:39:37 web.1 | connected: true,
17:39:37 web.1 | disconnected: false,
17:39:37 web.1 | handshake: [Object],
17:39:37 web.1 | _events: [Object] } },
17:39:37 web.1 | fns: [],
17:39:37 web.1 | ids: 0,
17:39:37 web.1 | acks: {},
17:39:37 web.1 | adapter:
17:39:37 web.1 | { nsp: [Circular],
17:39:37 web.1 | rooms:
17:39:37 web.1 | { '5MGPNOdO4th_dOuZAAAA': [],
17:39:37 web.1 | '64rUhxxp--4Qk1MqAAAB': [],
17:39:37 web.1 | RfgXeMgHeP_9SQC5AAAC: [Object],
17:39:37 web.1 | '7TEjGJjWzxObulClAAAD': [Object] },
17:39:37 web.1 | sids:
17:39:37 web.1 | { RfgXeMgHeP_9SQC5AAAC: [Object],
17:39:37 web.1 | '7TEjGJjWzxObulClAAAD': [Object] },
17:39:37 web.1 | encoder: {} },
17:39:37 web.1 | _events: { connection: [Function] } }
Мой код:
ЯВАСКРИПТ
if (game.scoreTeamTwo> game.scoreTeamOne && game.scoreTeamTwo> game.scoreTeamThree && game.scoreTeamTwo> game.scoreTeamFour) {
game.winner = 2;
io.sockets.emit ('CTFEnd', игра);
}
// Просто смотрит, выиграла ли команда 1 игру, и когда она это делает, выдает CTFEnd
и все остальные игровые данные
`` `` `
Нашел "решение" своей проблемы. Я могу отправить каждую отдельную часть данных, но он НЕ работает с объектами.
Я недавно тоже получал эту ошибку, с той лишь разницей, что это случается у меня только изредка. Все утро тестировал, и мне не удалось воспроизвести проблему.
Для меня это было то, что он не мог излучать кому-либо, только когда объект был слишком большим.
@BenBals, если объект слишком большой, то достойный обходной путь - отправить его в виде строки, т.е. запустить на нем JSON.stringify()
У меня есть другая работа, но я обдумал это.
: cry: вглядываясь в это
имеет ту же проблему при испускании объекта типа:
{success: file, content: file.content}, где file.content - это объект буфера, а все остальные свойства файла - это строки.
пришлось добавить содержимое поля непосредственно к объектам, потому что hasBin () проверяет только первый уровень объекта. Но когда он затем попытался отправить буфер, он получил `` Превышен максимальный стек вызовов ''
Вы можете реплицировать это, испуская объект сокета (по крайней мере, в одну сторону), поэтому (ниже будет сервер -> клиент)
socket.emit('crash', {socket:socket});
Мне любопытно, есть ли у этого реальное исправление.
Есть новости по этой проблеме?
РЕДАКТИРОВАТЬ: Моя проблема заключалась в том, что я пытался отправлять рекурсивные объекты.
Интересно, что я получаю ту же ошибку при попытке передать данные Firebase клиентской стороне.
Ошибка
node_modules/socket.io/node_modules/has-binary-data/index.js:46
for (var key in obj) {
^
RangeError: Maximum call stack size exceeded
На стороне сервера
var DB = new Firebase('https://1234abcd.firebaseIO.com');
var USERS = DB.child("users");
io.sockets.on('connection', function(socket){
socket.emit('test', {
db: USERS
});
});
Найти решение...
Извините, но мой китайский не так уж хорош. Не могли бы вы перевести это на английский?
Сделал Google Translate, и он выходит: "Найдите решение ..." ... вряд ли стоит отвечать. Для записи, решение состоит в том, чтобы не передавать такой большой объем данных через socket.io ... это сокет, который был разработан для быстрых и коротких ответов. Разбейте свой ответ или отправьте его через ajax. Отказ от подписки на эту ветку.
Одна вещь, которую вы можете сделать с помощью кода socket.io, - это просто асинхронно перебирать объект и его свойства, например:
var props = [];
var obj = { a: 1, b:2, c: { d: 3, e: 4 } };
function next_prop(callback){
if (!props.length){
setTimeout(callback);
return;
}
var prop = props.shift();
//do whatever with the prop, call parse_obj on it if it's an object
setTimeout(next_prop);
}
function parse_obj(obj, callback){
for (var i in obj){
props.push(i);
}
setTimeout(function(){next_prop(callback);});
}
parse_obj(obj);
Конечно, это не настоящий код, который вы должны использовать, потому что для каждого отдельного объекта должна быть оболочка функций на случай, если они вложены, иначе у вас будут конфликты с тем, какой объект анализируется.
Я тоже получаю эту ошибку, мой код такой: "io.sockets.emit ('key', data);"
Я пытаюсь упростить объект «данные» и сделать его маленьким, и это сработало.
--И я заглянул в код src, нашел это:
когда ваш объект «данные» имеет рекурсивную ссылку на атрибут, этот код выйдет из строя.
например, прото > прото > прото ...
+1 Может ли основная команда использовать асинхронную версию двоичной проверки, я могу помочь с этой настройкой
Я могу воспроизвести проблему, отправив объект сокета :)
+1 IE11 показывает "вне стека" в _hasBinary.
Эта ошибка показалась мне, когда я пытался отправить весь объект сокета обратно клиенту. Все, что мне действительно_ нужно, это socket.id
поэтому ошибка исчезла, когда я отправил обратно меньший элемент - в моем случае socket.id
вместо всего объекта socket
Вероятно, это произошло из-за того, что вы пытались отправить объект с круговыми ссылками, в результате чего рекурсивные вызовы превышали размер стека.
@LordMajestros Это исправило для меня! Спасибо
@GerbenHofman пожалуйста
Я столкнулся с такой же ошибкой на NodeJS v4.4.4 и socket.io v1.4.5.
В моем случае это происходит после события отключения.
И это происходит только тогда, когда я звоню на socket.emit
более 200 000 раз.
Если количество вызовов socket.emit
составляет около 100 000, эта ошибка никогда не возникает.
Параметр, который я использую с emit
, всегда является строкой
Эта информация вам помогает?
Чтобы добавить к @shunjikonishi , я видел, как это произошло, как только я отправил ровно 100 000 событий через io.emit. У меня подключен 1 сокет, поэтому кажется, что 100000 - это жесткий предел.
Похоже, это ограничение, наложенное Node (или средой выполнения JavaScript), и Socket.io содержит ссылку на что-то каждый раз, когда вы вызываете emit, поэтому, когда вы нажимаете 100000-й emit, он просто падает.
Протестировано с Node 5.11.0 и Socketio 1.4.8. Моя версия Node отличается (как и моя операционная система и т. Д., На самом деле не знаю, откуда взялись эти 100000), чем
Я запустил тот же самый код, используя ws.js, и он работал нормально, без проблем превысил 100000 излучаемых сокетов, так что, возможно, это проблема с Socket.io.
Есть ли шанс, что Socket IO реализует защиту от рекурсивных данных, излучаемых из и сбой с этой ошибкой? Простое обнаружение может предотвратить возникновение этой ошибки и вместо этого выдать более значимую ошибку, например «Возможно, вы пытаетесь отправить циклические данные». Это упростило бы отладку.
Есть довольно много достойных решений для обнаружения циклических данных: https://stackoverflow.com/questions/14962018/detecting-and-fixing-circular-references-in-javascript
Одно короткое решение полагается на JSON.stringify, чтобы найти проблему:
function isObjectCircular(obj) {
try {
JSON.stringify(circularReference);
} catch(err) {
return (err.toString() === 'TypeError: Converting circular structure to JSON');
}
return false;
}
Подробнее: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
@adamreisnz Добро пожаловать на пиар;)
Меня всегда застает врасплох, когда кто-то упоминает обо мне через 5 месяцев после того, как я оставил комментарий 😆
Я тоже встречал эту ошибку. Вот почему я трачу два часа на проверку всех кодов: <.
Я думаю, что это вызвано объектом рекурсии, таким как A = {B: {C: A}}, и, очевидно, сокет является объектом рекурсии.
На самом деле, я предполагаю, что это произошло потому, что в buffer.js они используют рекурсию для определения длины данных, которые вы хотите отправить. И затем получите «превышен максимальный размер стека вызовов». Если они используют JSON.stringify () для получения длины, будет еще одна явная ошибка, связанная с «круговой структурой». Между прочим, это плохое ключевое слово для Google!
Я тоже с этим столкнулся.
hasBin
заполнит стек рекурсивным циклом при попытке отправить объект, имеющий циклическую ссылку.
Шакс, я вижу, что уже 2 года существует PR, который исправит это:
@dustingraham исправление выглядит отлично, хотя я не уверен в последствиях для производительности.
Кроме того, даже если он больше не вызывает метод hasBinary
, я боюсь, что метод JSON.stringify, который вызывается позже в коде, все равно выдаст ошибку:
> var a = {};
undefined
> var b = { a: a };
undefined
> a.b = b
{ a: { b: [Circular] } }
> JSON.stringify(a)
Thrown:
TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
Самый полезный комментарий
Вероятно, это произошло из-за того, что вы пытались отправить объект с круговыми ссылками, в результате чего рекурсивные вызовы превышали размер стека.