Sharing websocket across browser tabs?


We want to have one socket per browser rather than one per tab in a browser. How can we achieve it? I read about shared web workers which was promising. A reference for that too is appreciated. Unfortunately shared web workers are not yet implemented by mozilla or internet explorer to the best of my knowledge. So what to do in this case ? We are working on node.js on server side.

After seeing this question, I've finally implemented sharing socket and added to my library a few days ago. It seems to work in most of browsers including even in IE6, but except Opera. For Opera, you may use regular checking instead of unload event.

Check releated issue at https://github.com/flowersinthesand/portal/issues/21

Leaving a cookie

  1. Set cookie to inform there is a shared socket.
  2. When socket closes, remove that cookie to inform there is no shared socket.

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

Sharing and using shared socket

  1. Using the storage event and localStorage - The localStorage fires the storage event when a value is set and removed.
    1. Check that StorageEvent and localStorage are supported.
    2. Add storage event handler which filters event by key. I used socket's url as key
    3. Add close event of socket which removes storage attributes
    4. To signal, set data with the previous key to storage

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

Using shared: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L851-893

  1. Using the window.open method - If we know a shared window's name, we can get that window's reference and access its property.
    1. Every browser supports the window.open method, but some browsers like Chrome prohibit to access the returned window's properties.
    2. Get or create iframe whose name attribute is key. I used socket's url, but note that IE doesn't allow to use non-word characters in name attribute of iframe tag.
    3. Iframe's contentWindow is a shared window reference. Set callbacks variable to store each window's listener.
    4. To signal, simply call callbacks with data. Note that IE 8 and less allow to pass only string to other window's function, and the shared window could be destoryed.

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

Using shared: https://github.com/flowersinthesand/portal/blob/7c2ce4bb61d05d80580e6cde6c94a78238a67345/jquery.socket.js#L894-929

Note

  1. In the above implementation, signalling is broadcasting, so the data should indicate the target. I used target property, p for parent and c for child.
  2. I used additional variables to share socket: opened - whether the shared socket is open, children - list of sharer. Codes and comments will help you understand details.

I hope my answer was helpful.


I used the localStorage object for communication between tabs in some occasions. The localStorage object has an event system to tell another tab or window of the same origin that some data has changed ( http://www.codediesel.com/javascript/sharing-messages-and-data-across-windows-using-localstorage/ ). The idea is, to let the tab with the socket write a timestamp and the received data into the localstorage. If the timestamp gets too old - maybe because the tab with the socket has been closed - another tab can start a socket-connection and update the data and timestamp.


I am using localStorage as a shared communication channel in order to send data between tabs using an interface identical to EventEmitters. Coupled with a leader election algorithm that decides which tab will be the one connected to the server, I relay all socket events to the leader tab from all follower tabs and vice versa. And finally, the leader tab forwards all events to the server, and broadcasts all received events to all other clients. Here's the code:


The answer as of 2016 must be Shared Web Workers as described in this Blog:

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


Far from ideal, but you can use a flash local connection to setup one websocket connection and then share it across tabs and multiple browsers.

See 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 for more information.


I'm still theorizing on this for a design I'm getting ready to start building. But, I'm thinking of combining

-WebSockets -Local Storage and -Cross Window Messaging

My theory is to create a socket engine in javascript that runs on every page load in every tab, but will shut down if one already has an established connection.

On first hit to the site, I'll have it make a GUID and store it in local storage, this guid will uniquely identify that users browser/login to their PC.

When the socket server accepts a connection it will have that guid, and any new request by that guid will return "999 Connection Already Established" or something like that.

Once one is running, It will seed the other tabs with cross window messaging by converting the data I want to share accross tabs to a JSON blob and then converting that back to an object when received in other tabs. So whichever tab get's the connection, will be handling all incoming/outgoing messages with the socket server. Then it will receive/transmit with the other tabs over cross window messaging. And in theory this should work with Iframe's and Popup windows as well.

This whole system will drive automatic data refreshes on loaded forms for a CRM like system we are building and a live chat system and ticket board.

My dream scenario, is if User A is staring at Ticket 1000 and User B updates ticket 1000 I want user A's ticket to refresh, and if user A made changes before it refreshed I want to give them a data migration pop up to prevent blowing away User B's changed

--User B Made a Conflicting Change while you are editing this record "UserB: FirstName -> Bob" [Take] "UserA: FirstName -> Robert" [Keep]


Don't think there seems to be a solution the way socket.io is implemented now. Check out Guillermo Rauch in thisvideo, fifth segment. He too considers it a challenge.


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

You need additional layer for cross-tab communication. Tabex has example for Faye use. Other websocket transports (socket.io and so on) can be used in similar way.


Actually,It's hard to avoid some of these problems, eg: Disconnect while the network is not stable.After all, pages are aim to exchange different text documents(such as the RFC documents) initially, which just needs a short ,low-cost and unstable transfer approach(the initial purpose of setting up HTTP protocol as I think)

Of course, to solve it, I suggest u to use the shared worker like the saying above or store the information of the shared and public part with the LocalStorage

Here is the link to the basic usage introduction of LocalStorage

hope it can really hope u!(Actually not yet)