0

I'm having difficulty figuring out the best method of sharing a WebSocket connection between multiple tabs. It seems like BroadcastEvent and SharedWorker are two modern APIs that can be used for this task. BroadcastEvent and SharedWorker seem like the solve the same problem, but I've seen solutions that use both together, something like this:

// worker.js

const socket = new WebSocket('url')
const broadcastChannel = new BroadcastChannel('example-broadcast')

socket.onmessage = ({ data }) => {
  broadcastChannel.postMessage(data)
}
// connection.js

const sharedWorker = new SharedWorker(new URL('worker.js', import.meta.url), {
  type: 'module',
  name: 'example-worker',
})
sharedWorker.port.start()
sharedWorker.port.onmessage = ({ data }) => {
  switch (data.type) {
    case 'message':
      console.log(data)
      break
  }
}

const broadcastChannel = new BroadcastChannel('example-broadcast')
broadcastChannel.addEventListener('message', ({ data }) => {
  switch (data.type) {
    case 'message':
      console.log(data)
      break 
  }
})

Is this a reasonable approach? Is it necessary to have both BroadcastChannel and SharedWorker here or can it be accomplished in a simpler manner? It's difficult to find answers about this situation that aren't from 2012 and use localhost and other outdated solutions.

Tania Rascia
  • 1,563
  • 17
  • 35
  • Given the sandboxing separating tab environments and the tools provided to deal with that, this seems like a logical approach to the problem. There's no shared websocket, so you'd need a way to host a non-shared websocket in some fashion. SharedWorker is a convenient way to do that. BroadcastChannel compliments this nicely and is easier to deal with than managing individual messaging for each tab. – Ouroborus Dec 28 '22 at 18:42
  • Note, though, that the usual scenario is that each tab maintains their own, private websocket and it's left up to the server to handle grouping/broadcasting. – Ouroborus Dec 28 '22 at 18:43
  • @Ouroborus Interesting, that's good to know. How would the server easily know that multiple connections are for the same client? It seems like it would be easier for the client to handle that, so I'm wondering why that's the preferred approach. – Tania Rascia Dec 28 '22 at 19:37
  • 1
    Different tabs are usually considered different clients. Authentication would allow the server to know that a particular user is using the site across multiple tabs. It depends on the app and it's very unusual for a modern, single app to want the user to operate across multiple tabs. – Ouroborus Dec 28 '22 at 21:23
  • What do you mean it's unusual for a modern, single app to want the user to operate across multiple tabs? Let's say I have a real-time dashboard that's streaming realtime audio and the user just happens to have 10 tabs open on the dashboard because they keep opening new ones, wouldn't I want to consolidate this to a single open WebSocket if possible? – Tania Rascia Dec 28 '22 at 22:33
  • It sounds like a good idea. And maybe it is. Though I'm not sure what you gain from it. It's just that today's strategy is to treat them as separate sessions with separate websockets. – Ouroborus Dec 28 '22 at 22:58
  • Do you have a resource about that being today’s strategy? I was going off the [Chrome developers page](https://developer.chrome.com/blog/broadcastchannel/#difference-with-sharedworkers) which stated, “for sharing a WebSocket connection with a remote host, shared workers are the most appropriate solution” so it would be helpful to compare with a resource talking about the one tab to one connection approach. – Tania Rascia Dec 29 '22 at 00:13
  • No, just going with experience. Keep in mind that Chrome, the browser, isn't the sole environment Google is interested in. At minimum, there's also Chrome OS. This approach makes a lot of sense in that environment. Also, I'm not saying it's a bad idea, just that it's unusual at the moment. It may come to be that this is common practice. Since your information is straight from the horse's mouth, so to speak, what doubts do you have about it specifically? Your question doesn't really say. Afaik, this is the only way to do this on the browser side. As I said, it's usually done on the server side. – Ouroborus Dec 29 '22 at 03:21
  • I’m always interested in finding and understanding best practices and making sure I do my due diligence before implementing something. My only doubt is that it’s hard to find up to date information and examples about this scenario, which is why I’m reaching out to the community. (And hopefully helping whoever comes along searching next.) – Tania Rascia Dec 29 '22 at 07:12

0 Answers0