Sessions/clients talking to each other

I have multiple iPads all talking to the same server and communicating with a separate program. Up until now, the sessions loaded on each iPad were distinct. They would control a separate part of the program and send separate OSC messages. I now have a use case in which an operation on ONE iPad needs to post a modal dialog on that iPad but post a different modal dialog on the other iPads. This state is not reflected in any communication to the main program or via OSC. The use modal is to post a confirmation dialog on the first iPad but lock out the others while this is happening.

My first thought was to create a modal button on the first iPad with an ID of "confim_modal" and then, on the other iPads have modals in which the button is disabled but the value of the modal button is linked, either by sharing a linkId or using "@{confirm_modal}" in the value field. Neither of these work.

I suspect that the client sessions are being treated as distinct things in which the ID and variable namespaces are separate. I haven't been able to find any documentation that spells out how servers, clients, and sessions behave in terms of namespaces... what it separate and what is shared. If I refer to a widget ID "fred" on one client can it see the other clients. What about variables.

Anyway, is there a recommended way to do this?

thanks,
Rob

The closest documentation regarding this is here: General mechanics - Open Stage Control

Id's and variables are not shared, there's only one synchronization logic between clients regarding widgets: when a widget sends a message, the server sends it back to the other clients so that widgets that send the same message are synchronized (it's done by comparing address, preArgs and target, id is ignored).

You'll probably need to dive into custom modules if you didn't already. Here is a quickly written example that might help you getting started:

// keep track of connected clients vs loaded session
var clientSession = {}

app.on('sessionOpened', (data, client)=>{
    clientSession[data.path] = client.id
})

module.exports = {

    oscOutFilter: function(data) {

        var {address, args, host, port, clientId} = data

        if (data.address === '/message/that/triggers/confirm/modal') {

            // activate modal in every client
            receive('/modal/address', 1)

            // or maybe do something different depending on the client
            for (var session in clientSession) {
                var id = clientSession[id]

                if (session.includes('sessionA.json')) {
                    receive('/modal/address', 1)
                } else {
                    // let's say other clients have a different modal that acts as screen locker
                    receive('/screen/lock', 1)
                }
                
            }


            // bypass the osc message
            return
        }

        else if (data.address === '/conrmation/from/modal/button') {

            // same idea as before
            
        }

        
        return data

    }

}

That link to General Mechanics really helped. I probably should have read that weeks ago.

The mention that clients link also by address gave me the idea that I could just make a "fake" OSC address that all the modals share. Using "/internal/modal_posted" as the address for all the modal dialogs ensures that they synchronize.

I had thought that, perhaps, a custom module on the server with some code might also be a solution but I was hoping there was something simpler. The common OSC address seems to work nicely.

Thanks!