Совместное использование веб-сокета на вкладках браузера? - PullRequest
35 голосов
/ 04 марта 2012

Мы хотим иметь один сокет на браузер, а не один на вкладку в браузере. Как мы можем достичь этого? Я читал об общих веб-работниках, которые были многообещающими. Ссылка на это тоже приветствуется. К сожалению, веб-работники с общим доступом еще не реализованы Mozilla или Internet Explorer, насколько мне известно. Так что же делать в этом случае? Мы работаем над node.js на стороне сервера.

Ответы [ 9 ]

8 голосов
/ 12 июля 2012

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

Проверьте опубликованную проблему на https://github.com/flowersinthesand/portal/issues/21

Оставив печенье

  1. Установить cookie для информирования о наличии общего сокета.
  2. Когда сокет закрывается, удалите этот файл cookie, чтобы сообщить об отсутствии общего сокета.

См., https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L629-650

Совместное использование и использование общего сокета

  1. Использование события хранилища и localStorage - LocalStorage запускает событие хранилища, когда значение устанавливается и удаляется.
    1. Убедитесь, что StorageEvent и localStorage поддерживаются.
    2. Добавить обработчик событий хранилища, который фильтрует событие по ключу. Я использовал URL сокета в качестве ключа
    3. Добавление события закрытия сокета, который удаляет атрибуты хранилища
    4. Для подачи сигнала установить данные с помощью предыдущего ключа в хранилище

Поделиться: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L531-568

Использование общего доступа: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L851-893

  1. Использование метода window.open - если мы знаем имя общего окна, мы можем получить ссылку на это окно и получить доступ к его свойству.
    1. Каждый браузер поддерживает метод window.open, но некоторые браузеры, такие как Chrome, запрещают доступ к свойствам возвращаемого окна.
    2. Получить или создать iframe, атрибут имени которого является ключевым. Я использовал URL сокета, но учтите, что IE не позволяет использовать не-словесные символы в атрибуте name тега iframe.
    3. iframe contentWindow - это ссылка на общее окно. Установите переменную callbacks для хранения слушателя каждого окна.
    4. Чтобы сигнализировать, просто вызовите обратные вызовы с данными. Обратите внимание, что IE 8 и менее позволяет передавать только строку в функцию другого окна, и общее окно может быть уничтожено.

Совместное использование: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L571-605

Использование общего доступа: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L894-929

Примечание

  1. В вышеприведенной реализации сигнализация является широковещательной, поэтому данные должны указывать цель. Я использовал целевое свойство, p для родителя и c для ребенка.
  2. Я использовал дополнительные переменные для совместного использования сокета: открытое - открыт ли общий сокет, дочерние - список общего ресурса. Коды и комментарии помогут вам разобраться в деталях.

Надеюсь, мой ответ был полезным.

6 голосов
/ 05 марта 2012

Я использовал объект localStorage для связи между вкладками в некоторых случаях.У объекта localStorage есть система событий, которая сообщает другой вкладке или окну того же происхождения, что некоторые данные изменились (http://www.codediesel.com/javascript/sharing-messages-and-data-across-windows-using-localstorage/).Идея состоит в том, чтобы позволить вкладке с сокетом записать метку времени и полученные данные в локальное хранилище.Если временная метка становится слишком старой - возможно, из-за того, что вкладка с сокетом была закрыта - другая вкладка может запустить соединение с сокетом и обновить данные и временную метку.

4 голосов
/ 14 октября 2012

Я использую localStorage в качестве общего канала связи для отправки данных между вкладками с использованием интерфейса, идентичного EventEmitters. В сочетании с алгоритмом выбора лидера, который решает, какая вкладка будет подключена к серверу, я передаю все события сокетов на вкладку лидеров со всех вкладок последователей и наоборот. И, наконец, вкладка «Лидер» перенаправляет все события на сервер и передает все полученные события всем остальным клиентам. Вот код:

3 голосов
/ 09 октября 2016

Ответ на 2016 год должен быть Shared Web Workers , как описано в этом блоге:

https://blog.pusher.com/reduce-websocket-connections-with-shared-workers/

3 голосов
/ 04 марта 2012

Далеко не идеально, но вы можете использовать локальное флэш-соединение для настройки одного соединения через веб-сокет, а затем делиться им между вкладками и несколькими браузерами.

См. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/LocalConnection.html?filter_flash=cs5&filter_flashplayer=10.2&filter_air=2.6 для получения дополнительной информации.

2 голосов
/ 21 июня 2014

Я все еще теоретизирую это для дизайна, который я собираюсь начать строить. Но я думаю объединить

-WebSockets -Местное Хранение а также Сообщения через окно

Моя теория заключается в создании механизма сокетов в javascript, который запускается при каждой загрузке страницы в каждой вкладке, но выключается, если уже установлено соединение.

При первом обращении к сайту я сделаю GUID и сохраню его в локальном хранилище, это уникальное удостоверение того, что пользователи просматривают / входят в систему на своем ПК.

Когда сервер сокетов принимает соединение, у него будет этот guid, и любой новый запрос от этого guid будет возвращать «999 Connection Уже Установлено» или что-то в этом роде.

Как только одна из них запустится, она запустит другие вкладки с кросс-оконным обменом сообщениями, преобразовав данные, которые я хочу разделить по вкладкам, в большой двоичный объект JSON, а затем преобразовав их обратно в объект при получении на других вкладках. Так что, какая бы вкладка ни была подключена, она будет обрабатывать все входящие / исходящие сообщения с сокет-сервером. Затем он будет получать / передавать с другими вкладками через кросс-оконный обмен сообщениями. И теоретически это должно работать и с окнами Iframe и Popup.

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

Сценарий моей мечты: если пользователь A смотрит на билет 1000, а пользователь B обновляет билет 1000, я хочу, чтобы билет пользователя A обновлялся, и если пользователь A вносил изменения до его обновления, я хочу, чтобы у него всплывала миграция данных до предотвратить снос пользователя B изменился

- Пользователь B внес конфликтующее изменение во время редактирования этой записи "UserB: FirstName -> Bob" [Take] "UserA: FirstName -> Robert" [Keep]

1 голос
/ 31 октября 2015

См. https://github.com/nodeca/tabex

Вам нужен дополнительный слой для связи между вкладками. У Tabex есть пример использования Faye. Другие транспорты веб-сокетов (socket.io и т. Д.) Могут использоваться аналогичным образом.

1 голос
/ 04 марта 2012

Не думайте, что, похоже, есть решение, как сейчас реализуется socket.io.Проверьте Гильермо Рауха в этом видео, пятый сегмент.Он тоже считает это проблемой.

0 голосов
/ 05 марта 2019

На самом деле, трудно избежать некоторых из этих проблем, например: Отключиться, пока сеть не стабильна. В конце концов, страницы изначально предназначены для обмена различными текстовыми документами (например, документами RFC), для чего требуется короткое недорогой и нестабильный подход к передаче (первоначальная цель установки протокола HTTP, как мне кажется)

Конечно, чтобы решить эту проблему, я предлагаю вам использовать совместно используемого работника, как указано выше, или хранить информацию о совместно используемой и общедоступной части с LocalStorage

Вот ссылка на введение по основному использованию LocalStorage

надеюсь, что это действительно может надеяться на тебя! (На самом деле еще нет)

...