Ответ 1
Способ, которым это работает во всех браузерах, заключается в том, что каждый домен получает ограниченное количество соединений, а ограничения являются глобальными для всего вашего приложения. Это означает, что если у вас есть одно соединение для обмена в реальном времени, у вас есть меньше всего для загрузки изображений, css и других страниц. Кроме того, вы не получаете новых подключений для новых вкладок или окон, все они должны иметь одинаковое количество соединений. Это очень расстраивает, но есть веские причины для ограничения соединений. Несколько лет назад этот предел составлял 2 во всех браузерах (в соответствии с правилами в (http://www.ietf.org/rfc/rfc2616.txt) спецификацией HTTP1.1), но теперь большинство браузеров используют 4-10 соединений вообще. Для мобильных браузеров, с другой стороны, по-прежнему необходимо ограничить количество подключений для экономии заряда аккумулятора.
Эти трюки доступны:
- Используйте больше имен хостов. Назначая ex. www1.domain.com, www2.domain.com, вы получаете новые подключения для каждого имени хоста. Этот трюк работает во всех браузерах. Не забудьте изменить домен cookie, чтобы включить весь домен (domain.com, а не www.domain.com).
- Используйте веб-сокеты. Веб-сокеты не ограничены этими ограничениями, и, что более важно, они не конкурируют с остальными вашими веб-сайтами.
-
Повторное использование такого же соединения при открытии новых вкладок/окон. Если вы собрали всю коммуникационную логику реального времени в концентратор объектов, вы можете вызвать этот объект во всех открытых окнах, как это:
window.hub = window.opener ? window.opener.hub || new Hub()
- или использовать flash - не самый лучший совет в наши дни, но он все равно может быть вариантом, если веб-узлы не являются опцией.
- Не забудьте добавить несколько секунд времени между каждым запросом SSE, чтобы разрешить очистку запросов в очереди, прежде чем запускать новый. Также добавьте немного больше времени ожидания для каждой секунды, когда пользователь неактивен, таким образом вы можете сконцентрировать ресурсы сервера на активных пользователях. Также добавьте случайное число задержек, чтобы избежать проблемы Громового стада
Еще одна вещь, которую следует помнить при использовании многопоточного и блокирующего языка, такого как Java или С#, вы рискуете использовать ресурсы в своем длинном запросе на опрос, который необходим для остальной части вашего приложения. Например, в С# каждый запрос блокирует объект Session, что означает, что все приложение не отвечает в течение времени, когда запрос SSE активен.
NodeJs отлично подходит для этих вещей по многим причинам, как вы уже выяснили, и если вы используете NodeJS, вы бы использовали socket.io или engine.io, который заботится обо всех этих проблемах для вас, используя веб-порты, флеш-память и XHR-опрос, а также потому, что он не является блокирующим и однопоточным, что означает, что он будет потреблять очень мало ресурсов на сервере, когда он ждет отправки вещей. Приложение С# потребляет один поток на запрос ожидания, который занимает не менее 2 МБ памяти только для потока.