Specify session file in url?

I can't seem to find any references to this, but apologies if it's been asked, answered, or documented and I haven't found it.

I'm wondering if it's possible for the client to specify the Session file to load through the URL. Something like: http://127.0.0.1:8080/?session=mytemplate.json

If not, maybe there's another way to accomplish what I'm looking to do.

I'd like to have different shortcuts to open different session files that will remember where they're positioned and their window sizes. For example, suppose I have a "Setlist.json" that I want to just sit as a vertical strip on the left side of the screen. It's just a list of songs where I can click on the one I want. I size it to something like 150x1000 anchored to the top left corner.

In a different window I have a control surface called "Controls.json". Let's say I want that 800x600 and I'll put that in the bottom right.

On Windows I can configure shortcuts that will open up the windows (in Chrome) at the right size and location and connect to the OSC server, but they always want to open the default session.

Am I missing something obvious?

1 Like

you can read in the "server json" session file. you can take a look in my project where i do exactly this.

you can also find examples in the forum (this or a similar question has been asked.

Hope this helps.

Thank you for the response, although I'm not sure it addresses the question.

To be more clear, I will be opening two or more different OSC client windows to use at the same time. These may or may not be on the same system that's running the OSC server.

I'd like to be able to click a shortcut on my desktop to open the first one, let's call it SessionA and have it open a Chrome browser at the size, location, and with the properties I specify in the shortcut. It will connect to the URL where the OSC server is running, such as http://127.0.0.1:8080.

Then I want to be able to click a second shortcut, call it SessionB, and have it do the same. That will open with its own size, location, and properties. It will be running a different session file. Let's call them SessionA.json and SessionB.json.

Creating the shortcuts to open the different windows at the sizes and locations I want is not a problem. The only issue is they will both open up with the same default Session configured at the server.

I'm thinking about the Client Options feature available through the URL specification. I'm just not aware of a way to pass a session file name in that way.

Because the clients may be running on different systems than the host I don't want to take the approach of starting multiple hosts with different default session files. Thus my preference to do it through the URL if possible.

With the client url option "id" and a custom module you can do that:

var sessions = {
    'clientA': 'path/to/a.json', // for client loading "http://server:port?id=clientA"
    'clientB': 'path/to/b.json' // for client loading "http://server:port?id=clientA"
}

app.on("open", (data, client)=>{
    if (sessions[client.id]) {
        receive('/SESSION/OPEN', sessions[client.id], {clientId: client.id})
    }
}

Edit: missing coma added thanks to @rawbengal

1 Like

Thank you, that's an interesting approach I wouldn't have thought of.

Some quick comments on this, as I needed to solve an almost identical issue. The code fragment has a couple of syntax errors. Included here is the corrected version:

var sessions = {
    'clientA': 'path/to/a.json', // for client loading "http://server:port?id=clientA"
    'clientB': 'path/to/b.json' // for client loading "http://server:port?id=clientB"
}

app.on("open", (data, client)=>{
    if (sessions[client.id]) {
        receive('/SESSION/OPEN', sessions[client.id], {clientId: client.id})
    }
})

With this version, I was able to get things working but I had to leave out the "--load" option in my server command line, otherwise it would always load that session file. In order to ensure that I always get something, I modified the example as follows:

var default_session = 'path/to/default.json'
var sessions = {
    'clientA': 'path/to/a.json', // for client loading "http://server:port?id=clientA"
    'clientB': 'path/to/b.json' // for client loading "http://server:port?id=clientB"
}

app.on("open", (data, client)=>{
    receive('/SESSION/OPEN', sessions[client.id] || default_session, {clientId: client.id})
})

In my case 'default.json' is a panel with a text error message saying there was an unexpected ID. This would indicate a configuration error on the client/kiosk side.

cheers,
Rob

1 Like

Thanks for the correction !

Revisiting this.... I am seeing generally weird behavior at times, that really feels related to the usage of the id=XXX hack to force a specific session file. Is there ANY other recommended way to handle this that doesn't involve changing the client ID? I need the client URL to allow me to choose one of four different session files.
Lately I've started to see a lot of communication started/stopped notifications on the client when I use "id=XXX" URLs but they go away when I get rid of the ID.

See Inconsistent behavior between machines. server.js error - #9 by jean-emmanuel

Replying here because this discussion seems more on-topic with the original question.

To avoid using the id here's what could work:

  • create an empty session with this in the root's onCreate script:
send('127.0.0.1:10000', '/session', globals.env.session)

this session will act like a hub and send the "session" parameter found in the url (like you did with the id)

  • set the server's load option to that hub session file
  • in the custom module, catch the outgoing /session message and use it to make the client load the session you want.

I have done this and it mostly works, thanks!

My custom module looks like this:

const default_session = 'default.json'
const sessions = {
    '1': 'one.json', // for client loading "http://server:port?session=1"
    '2': 'two.json', // for client loading "http://server:port?session=2"
    '3': 'three.json' // for client loading "http://server:port?session=3"
}

module.exports = {
    oscOutFilter:function(data){
        if (data.address === '/session') {
        	// don't actually send a message, load the desired session file
            receive('/SESSION/OPEN',
                (sessions[data.args[0].value] || default_session),
                {clientId: data.clientId}
            )
        }
        else {
        	return data
        }
    }
}

However this will NOT actually redirect from the "hub" session file to the target session file unless I add a small delay on create. This feels a little fishy too me as I suspect all I am doing is trying to fix some race condition with a delay. Eventually I'll hit some time when I lose the race and my session doesn't load. It also doesn't look very "professional" because my interface flashes when I reload due to the delay. Any ideas? For reference, this is what I ended up using for the onCreate script in the hub.json file:

  setTimeout(() => {
    send('127.0.0.1:10000', '/session', globals.env.session)
  }, 100)  // delay 100ms

cheers,
Rob

Hmm I didn't think of that: the root's onCreate is called before the session has finished loading and that's why the client /SESSION/OPEN is ignored. Here's a reliable solution (with no timeout in onCreate):

const default_session = 'default.json'
const sessions = {
    '1': 'one.json', // for client loading "http://server:port?session=1"
    '2': 'two.json', // for client loading "http://server:port?session=2"
    '3': 'three.json' // for client loading "http://server:port?session=3"
}

// clientId vs session id
var clientSessions = {}

app.on('sessionOpened', (data, client)=>{
    if (data.path.endsWith('hub.json')){
        var sessionPath = sessions[clientSessions[client.id]] || default_session
        // load session when hub session has finished loading
        receive('/SESSION/OPEN', sessionPath, {clientId: client.id})
    }
})

module.exports = {
    oscOutFilter:function(data){
        if (data.address === '/session') {
            // store session for client
            clientSessions[data.clientId] = data.args[0].value
        }
        else {
        	return data
        }
    }
}

This seems to work well. Thank you!

I made a slight tweak to what you did, so I'll include it here in case it helps anyone. I moved the selection of which session to load into the "hub.json" session and eliminated the test for the name of the starting session file. I think this has the same result but makes the solution a little more portable.

// put send('127.0.0.1:10000', '/RedirectSession', 'newsession.json') in root onCreate

// clientId vs session id
var session_redirects = {}

app.on('sessionOpened', (data, client)=>{
    redirect = session_redirects[client.id]
    if (redirect !== undefined) {
        // redirect the session if a RedirectSession message was received
        delete session_redirects[client.id]
        receive('/SESSION/OPEN', redirect, {clientId: client.id})
    }
})

module.exports = {
    oscOutFilter:function(data){
        if (data.address === '/RedirectSession') {
            // store session for client
            session_redirects[data.clientId] = data.args[0].value
        }
        else {
            return data
        }
    }
}