Переопределить поведение setTimeout для неактивных вкладок

В настоящее время я разрабатываю одноранговую игру на JavaScript с использованием WebRTC. Он рассматривает один из одноранговых узлов (то есть хост) как сервер, а любые другие одноранговые узлы, которые присоединяются, подключаются к узлу через посреднический сервер node.js.

В настоящее время я пытаюсь решить проблему, из-за которой игра перестает обновляться для всех, если хост переключает вкладки, так что игра больше не является активной вкладкой. Проведя небольшое исследование, я обнаружил, что это потому, что я использую что-то вроде:

setTimeout(callback, 1000 / 60);

в моем игровом цикле. setTimeout (по крайней мере, в Chrome и Firefox, которые являются браузерами, которые меня интересуют) определяется таким образом, что если вызывающая его страница не находится на вашей активной вкладке, ее можно вызывать максимум один раз в секунду.

Я читал, что у веб-воркеров нет этого ограничения, но для того, чтобы это работало, мне нужно было бы запустить всю мою игровую логику внутри веб-воркера. Я попытался отправить свой игровой объект рабочему с помощью JSON.stringify (), но он сказал, что объект имеет круговую ссылку (в игровом цикле) и его нельзя преобразовать в JSON. Так что я не уверен, что с этим делать.

Я также рассмотрел возможность реализации своего собственного таймера, который продолжал работать независимо от того, была ли страница на активной вкладке, но я тоже не знаю, как это сделать.

У меня действительно нет проблем с тем, чтобы сделать это любым из этих способов или даже каким-то другим способом, о котором я еще не думал, при условии, что это не влечет за собой больших накладных расходов на производительность. Любые предложения будут ценны.


person Damandatwin    schedule 04.05.2014    source источник
comment
Вы можете загрузить свой скрипт в воркер (через importScripts). В качестве альтернативы вы можете использовать worker для отправки сообщений по таймеру, поскольку у них нет этого ограничения, и использовать функцию обратного вызова в качестве обработчика событий.   -  person Benjamin Gruenbaum    schedule 04.05.2014
comment
peer to peer Это не одноранговый узел, если у него есть выделенный хост / сервер ... но в любом случае.   -  person Metalstorm    schedule 04.05.2014
comment
Это не выделенный сервер. Просто один из пиров рассматривается как сервер и отвечает за состояние игры.   -  person Damandatwin    schedule 04.05.2014
comment
Бенджамин, я попробую сейчас и вернусь к тебе.   -  person Damandatwin    schedule 04.05.2014
comment
Хорошо, в итоге я исправил это, сделав что-то похожее на то, что сказал Бенджамин. Однако мне действительно нужно было, чтобы веб-воркер вызвал setTimeout, поэтому единственное, что он сделал, это: setTimeout (postMessage, 1000/60); Должен ли я дать более подробный ответ, описывающий то, что я сделал, чтобы все увидели?   -  person Damandatwin    schedule 04.05.2014
comment
Да, это было бы мило. Вы можете получить за это голоса и принять ответ.   -  person Bergi    schedule 06.05.2014


Ответы (1)


Итак, как я сказал выше, веб-воркеры могут вызывать setTimeout () без задержки в 1 секунду для неактивных вкладок. Моим решением было создать Web Worker, который отвечал только за вызов setTimeout () (вызываемый в его прослушивателе событий onmessage). Затем в конце каждого игрового цикла я вызвал:

this.worker.postMessage(null)

Можно утверждать, что было бы более эффективно возложить на Web Worker больше ответственности, чем просто вызвать setTimeout (), поскольку я уже добавил накладные расходы на ожидание отправки сообщений между основным потоком и рабочим. Это то, на что я мог бы взглянуть в будущем.

Основная проблема, связанная с этим способом, - совместимость с IE; IE не поддерживал веб-работников до версии 10.0. Меня это не беспокоит, но я думаю, что стоит упомянуть.

person Damandatwin    schedule 08.05.2014
comment
@ElSajko привет, какая альтернатива этому? также есть ли у вас справочная ссылка, чтобы поделиться тем, что она больше не работает - person ɹɐqʞɐ zoɹǝɟ; 29.05.2018
comment
@ ɹɐqʞɐzoɹǝɟ он снова работает, нет никаких подробностей, что это не сработало. Надеюсь, это больше не изменится. - person ElSajko; 29.05.2018