0

I'm looking for the best approach to synchronize events between two instance of the same application.

It's a trading simulator, the idea is to have market replay synchronized on all pairs (hence on all windows). I want to share a time cursor (type DateTime or a Timestamp) the speed (type Int), and the state (functionally an Enum {playing, paused} assuming I'll need more state, if not, a Boolean will do)

The straightforward and first idea would be to use websockets and have a server handle the time cursor, but I was wondering if that was doable purely client side.

It's definitely possible, with window.localStorage , but It's both hacky and questionable on the performance side.

I have never touched at WebRPC, so it may be a lead, I would like mere directions pointed towards, if ever I find a clean way to achieve what I'm looking for, I'll share the whole boilerplate here.

Edit: Oh, by the way, the hacky solution with window.localStorage would look like this (I've implemented it a bit differently because I'm using a framework, so this is the agnostic version)

Again, I'm quite confident it is questionable on many level and the whole point of this post is to find a better way.

My strategy is to set an unique ID for each window: the following post gives a way to do that In javascript, how can I uniquely identify one browser window from another which are under the same cookiedbased sessionId

then, We have to share this id with other instances, since (at my knowledge) there is no lock mechanism for window.localStorage, we'll use randomness


export const stateSyncronizer = {
    getParticipants(){
        return JSON.parse(window.localStorage.myPubSub??'[]')
    },
    init(){
        return new Promise((resolve, reject) => {

            setTimeout(() => {
                window.myPubSubId ??= Date.now()
                const participants = getParticipants()
                participants.push(window.myPubSubId)
                window.localStorage.myPubSub = JSON.stringify(participants)
                resolve()
            }, Math.random() * 1000)
        }

    },
    syncState(stateGetter, callback) => {
    if(Math.min(...getParticipants() === window.myPubSubId){
        // we are the first instance
        window.localStorage.myPubSubState = JSON.stringify(stateGetter())
    }
    callback(JSON.parse(window.localStorage.myPubSubState))

}

}

// then at application bootstrap we something like:
import {stateSyncronizer} from 'filepath'

stateSyncronizer.init().then(()=>{
    setInterval(
        ()=>stateSyncronizer.syncState(/* put stateGetter & callback here */),
        1000 // it's for the sake of simplicity, but avoid magic numbers and use a config file !
        )
    
})


Edit2: I'll do some tests and benchmarks, it may not be so awful though quite inelegant IMO, also, I have only tested the mechanism on Firefox, I'm not 100% certain localStorage mutation are propagated as they happen on every browser, though I'd be surprised if not.

I'll post the results here

0 Answers0