web-dev-qa-db-fra.com

Vous partagez le Websocket entre les onglets du navigateur?

Nous voulons avoir un socket par navigateur plutôt qu'un par onglet dans un navigateur. Comment pouvons-nous y parvenir? J'ai lu sur les travailleurs Web partagés qui étaient prometteurs. Une référence pour cela aussi est appréciée. Malheureusement, les utilisateurs Web partagés ne sont pas encore mis en œuvre par Mozilla ou Internet Explorer à ma connaissance. Alors, que faire dans ce cas? Nous travaillons sur node.js côté serveur.

36
singhsumit

Après avoir vu cette question, j'ai finalement implémenté le partage de socket et ajouté à ma bibliothèque il y a quelques jours. Il semble fonctionner dans la plupart des navigateurs, même dans IE6, mais à l'exception d'Opera. Pour Opera, vous pouvez utiliser la vérification régulière au lieu de l'événement de déchargement.

Vérifiez le problème lié à https://github.com/flowersinthesand/portal/issues/21

Laisser un cookie

  1. Définissez un cookie pour informer qu'il existe une socket partagée.
  2. Lorsque le socket se ferme, supprimez ce cookie pour indiquer qu'il n'y a pas de socket partagé.

Voir, https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L629-65

Partage et utilisation de socket partagé

  1. Utilisation de l'événement de stockage et de localStorage - Le localStorage déclenche l'événement de stockage lorsqu'une valeur est définie et supprimée.
    1. Vérifiez que StorageEvent et localStorage sont pris en charge.
    2. Ajoutez un gestionnaire d'événements de stockage qui filtre l'événement par clé. J'ai utilisé l'URL de socket comme clé
    3. Ajouter un événement close de socket qui supprime les attributs de stockage
    4. Pour signaler, définissez les données avec la clé précédente sur le stockage

Partage: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L531-568

Utilisation de partage: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L851-89

  1. Utilisation de la méthode window.open - Si nous connaissons le nom d'une fenêtre partagée, nous pouvons obtenir la référence de cette fenêtre et accéder à sa propriété.
    1. Chaque navigateur prend en charge la méthode window.open, mais certains navigateurs comme Chrome interdisent d'accéder aux propriétés de la fenêtre renvoyée.
    2. Obtenez ou créez un iframe dont l'attribut de nom est clé. J'ai utilisé l'URL de socket, mais notez que IE ne permet pas d'utiliser des caractères non Word dans l'attribut name de la balise iframe.
    3. ContentWindow de Iframe est une référence de fenêtre partagée. Définissez la variable de rappel pour stocker l'écouteur de chaque fenêtre.
    4. Pour signaler, il suffit d'appeler des rappels avec des données. Notez que IE 8 et moins permet de ne passer que de la chaîne à la fonction d'une autre fenêtre, et la fenêtre partagée pourrait être détruite.

Partage: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L571-605

Utilisation partagée: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L894-929

Remarque

  1. Dans la mise en œuvre ci-dessus, la signalisation est en cours de diffusion, les données doivent donc indiquer la cible. J'ai utilisé la propriété cible, p pour parent et c pour enfant.
  2. J'ai utilisé des variables supplémentaires pour partager le socket: ouvert - si le socket partagé est ouvert, enfants - liste des partageurs. Les codes et les commentaires vous aideront à comprendre les détails.

J'espère que ma réponse a été utile.

8
Donghwan Kim

J'ai parfois utilisé l'objet localStorage pour la communication entre les onglets. L'objet localStorage possède un système d'événements pour indiquer à un autre onglet ou fenêtre de la même origine que certaines données ont changé ( http://www.codediesel.com/javascript/sharing-messages-and-data-across-windows -using-localstorage / ). L'idée est de laisser l'onglet avec le socket écrire un horodatage et les données reçues dans le stockage local. Si l'horodatage devient trop ancien - peut-être parce que l'onglet avec le socket a été fermé - un autre onglet peut démarrer une connexion de socket et mettre à jour les données et l'horodatage.

6
Alex

J'utilise localStorage comme canal de communication partagé afin d'envoyer des données entre les onglets à l'aide d'une interface identique à EventEmitters. Couplé avec un algorithme d'élection de leader qui décide quel onglet sera celui connecté au serveur, je relaie tous les événements de socket vers l'onglet leader depuis tous les onglets suiveurs et vice versa. Enfin, l'onglet leader transfère tous les événements au serveur et diffuse tous les événements reçus à tous les autres clients. Voici le code:

5
Kaustubh Karkare

La réponse à partir de 2016 doit être Shared Web Workers comme décrit dans ce blog:

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

5
vanthome

Loin d'être idéal, mais vous pouvez utiliser une connexion locale flash pour configurer une connexion Websocket, puis la partager entre des onglets et plusieurs navigateurs.

Voir 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 pour plus d'informations.

3
Tom

Je suis encore en train de théoriser à ce sujet pour une conception que je me prépare à commencer à construire. Mais je pense à combiner

-WebSockets -Stockage local et -Message de fenêtre croisée

Ma théorie est de créer un moteur de socket en javascript qui s'exécute à chaque chargement de page dans chaque onglet, mais s'arrêtera si l'on a déjà une connexion établie.

Au premier accès au site, je vais lui faire faire un GUID et le stocker dans le stockage local, ce guide identifiera de manière unique que les utilisateurs naviguent/se connectent à leur PC.

Lorsque le serveur de socket accepte une connexion, il aura ce GUID et toute nouvelle demande de ce GUID renverra "999 Connection déjà établie" ou quelque chose comme ça.

Une fois que l'un est en cours d'exécution, il amorcera les autres onglets avec une messagerie inter-fenêtres en convertissant les données que je souhaite partager entre les onglets en un objet blob JSON, puis en les reconvertissant en objet lorsqu'ils sont reçus dans d'autres onglets. Quel que soit l'onglet obtenu, la connexion gérera tous les messages entrants/sortants avec le serveur de socket. Ensuite, il recevra/transmettra avec les autres onglets via la messagerie inter-fenêtres. Et en théorie, cela devrait également fonctionner avec les fenêtres Iframe et Popup.

L'ensemble de ce système entraînera des actualisations automatiques des données sur les formulaires chargés pour un système de type CRM que nous construisons et un système de chat en direct et un tableau de tickets.

Mon scénario de rêve est que si l'utilisateur A regarde le ticket 1000 et que l'utilisateur B met à jour le ticket 1000, je veux que le ticket de l'utilisateur A soit actualisé, et si l'utilisateur A a apporté des modifications avant qu'il ne soit actualisé, je veux leur donner une fenêtre de migration de données pour éviter de souffler. L'utilisateur B a changé

--L'utilisateur B a apporté un changement conflictuel pendant que vous modifiez cet enregistrement "UserB: FirstName -> Bob" [Take] "UserA: FirstName -> Robert" [Keep]

3
Ryan Mann

Ne pensez pas qu'il semble y avoir une solution de la façon dont socket.io est implémenté maintenant. Découvrez Guillermo Rauch dans cette vidéo, cinquième segment. Lui aussi considère cela comme un défi.

1
almypal

Voir https://github.com/nodeca/tabex

Vous avez besoin d'une couche supplémentaire pour la communication croisée. Tabex a un exemple d'utilisation de Faye. D'autres transports Websocket (socket.io et ainsi de suite) peuvent être utilisés de la même manière.

1
Vitaly

En fait, il est difficile d'éviter certains de ces problèmes, par exemple: se déconnecter alors que le réseau n'est pas stable.Après tout, les pages visent à échanger différents documents texte (tels que les documents RFC) au départ, ce qui nécessite juste un court, à faible coût et approche de transfert instable (le but initial de la mise en place du protocole HTTP comme je pense)

Bien sûr, pour le résoudre, je vous suggère d'utiliser le travailleur partagé comme le dicton ci-dessus ou de stocker les informations de la partie partagée et publique avec le LocalStorage

Voici le lien vers l'introduction d'utilisation de base de LocalStorage

j'espère qu'il peut vraiment vous espérer! (En fait pas encore)

0
Chopping