javascriptsocket.iolocal-storagelong-pollingsingle-page-application

How is it possible to share single js resource between browser tabs?


For example I want to refresh chat messages by multiple tabs with socket.io, longpolling, etc... whatever I have... For that I want to use only a single connection for all of the tabs. How can I make this? I can store the common data in localStore, cookies, etc... And I need some kind of semaphore which gives only a single synchronizer resource to one of the tabs, and after that tab is closed, it gives to another tab, etc... How is that possible? The only solution came in my mind to tell the localStore with onbeforeunload that the resource is free, but this does not work in every browser. Is there another option?


Solution

  • The keywords in this problem is "inter-tab communication", "cross-window messaging", etc...

    One solution is similar to long-polling: inter-tab-communication-using-local-storage/ Periodically ask the localStore/cookies for changes, and add a queue to allocate common resources (e.g. socket.io connection). You can use onbeforeunload or timeout to determine whether a tab/window is navigated away or closed. After that shortly the next tab in the queue will allocate the resource...

    The second solution is to use "localStore storage events" for the same. In that case you don't have to periodically ask the localStore (if onbeforeunload event is available). According to this: localStorage eventHandler Doesn't Get Called storage events are designed to affect only other tabs, so they are a good choice for intertab communication. The only problem is onunload: local storage on window unload event . So because of the lack of onunload support the first solution could be better.

    The third solution would be the usage of "shared webworkers", but they have not been implemented yet in several browsers (internet explorer), or they cannot open socket (firefox). So currently they are not an option, maybe 1-2 years later after bug fixes... Here is a demo - works chrome only - html5-shared-web-worker-examples.

    The fourth solution would be window.postMessage, which has not complete browser support currently. I read about it in some sto questions, and they all wrote that postMessage is not capable for what we want. I did not check the exact details about that function, it does not worth the time I think... There is an example about cross domain cross iframe communication: Cross-Domain iframe communication but same domain cross window communication is not possible with that I think.

    The fifth solution would be using cookies but in that case every tab should ping document.cookie because there in no cookie change event, like storage event in localstore. BNC Connector uses this approach.

    The sixth solution would be using WebSQL. Its driver is async non blocking, so it would be better than localStorage, but currently it is not supported by firefox and msie.

    Conclusion:

    Nowadays - 2013.10.03 - the best option to periodically ping the localStore from the resource utilizer tabs. The other tabs should listen to the storage event of the timestamp updates. If that event does not come in time, than the resource utilizer tab has timeout, and the next tab in the queue should get the resource. Maybe later the onunload event or the shared workers will be reliable, but currently they are not good enough...

    Solution:

    I found an implementation of the approach described in the conclusion: intercom.js I added an issue about a general interface of resource sharing, but in my case the single socket.io resource is good enough...