I have single WS connection per page (WebsocketProvider).
Main idea is to reduce overall bandwidth by having single connection per user (multiple browser tabs - 1 Websocket connenction). Because each time when user open new tab, he fetch all data from WS.
I am going to place WebsocketProvider connection into the SharedWorker. Also, I need pass YDoc into this provider. In such case, I think I can receive updates and send them to main thread and vise versa. It can help to have single source of truth (Shared Worker) for all tabs.
But I can’t share instances from Shared Worker (only copied objects). I need WebsocketProvider for TipTap extension such as Collaboration Cursor in the main thread.
Probably I need to implement some kind of proxy for main thread for data replication to shared worker and then integrate it with WebsocketProvider
Maybe someone already implemented such case or have any ideas about that?
You might be able to use SharedArrayBuffer to share updates across tabs without copying them every time. That can get pretty expensive.
Also, you’re probably already aware, but SharedWorker does not yet have good mobile browser support, so I only recommend using it in desktop-only scenarios.
WebsocketProvider does already do some special handling to ensure it works correctly across multiple tabs. You may want to look into that if you haven’t already to see if it affects your implementation.
If you are already multiplexing multiple docs over the websocket, it wouldn’t appear too difficult to have one global worker instance for which to subscribe to. You can basically just wrap a WebSocket into its own pub/sub service and then broadcast the messages back to the WebsocketProviders.
I wouldn’t worry about data replication too much. Maybe use WeakRefs to ensure objects wont accumulate after being processed. For SharedArrayBuffers, you need special CORS policies. Debugging workers can be quite complicated though.
@raine Thanks a lot for your answer!
Yeah, I am already implemented updates sharing between tabs via BroadcastChannel, also into SharedWorker.
Yes, I know about SharedWorker support and going to fallback this case. It’s okay for me.
I already dived deeper into WebsocketProvider handling.
But I doesn’t fit for my case completely. I decided to place WebsocketProvider into SharedWorker finally.
@TeemuKoivisto Thanks for a lot for your answer!
It make sense. As soon as I manage to implement something around the WebsocketProvider, I will share the result.
We accomplished something very similar to your goal by using RxDB. This stores your data by default in IndexDB on the client device, but if you don’t want to persist the data it can also use an in-memory database. RxDB elects a single master tab/process for the WebSocket connection and communication with the API. If the master goes away, then it elects a new master.
If you don’t want to use RxDB, then the concept of electing a master tab/process may be a reasonably simple solution to your problem.
Hope this is useful.