Hello there, thank you for making such an incredibly useful utility with this, I am totally amazed by it! I hope I can get some help as I am I am a little stuck here, not sure what I should be doing. I am trying to get the thrustFwdReport text widget to display data specific to that client, after a round trip through Unreal. In this case, the orange button is tapped in time with the kick drum of the music (represented as a live stream of midi data). The action is complete when the button is released, and then the OSC data is sent back to the client along with a string of that client's ID : I am recording the timing accuracy of the user's button press/release cycle, as well as recording the length of time the button was held. This is then combined to a float and sent back to the client, with their clientId appended as a second arg. So for each user, I want the thrustFwdReport text indicator to give that user a readout of their score so they can get a feel for how good their timing has been in order to make adjustments.
Back in my custom module I am matching args[1] to myClientId, and then just asking for the float args[0] to be returned.... however this is still updating all the clients... what am I missing?
Messages passing trough oscInFilter (via the return statement) are dispatched to all clients, you'll want to to use the receive()
function to send a message to a single client instead:
if (conditions_are_met) {
receive(data.address, args[0], {clientId: single_client_id})
return // empty return to prevent the original message from passing through
}
Also the logic behind your myClientId
variable doesn't seem very robust (what happens if a second client sends a message before the reply for the first one has been received ?), you might want to always use the clientId that's in the incoming message (if there's one) instead of comparing it to a possibly outdated local variable.
yes that's exactly what I want to do... but I couldn't figure out how to get the variable have tried a lot of different things but I am stumped by this... I think I need to get myClientId in the oscInFilter block of code but I can't figure a way how...
var myClientId = {}
var clients = []
app.on('open', (data, client) => {
myClientId = client.id
console.log(myClientId)
if (!clients.includes(client.id)){
clients.push(client.id)
}
})
app.on('close', (data, client) => {
if (clients.includes(client.id)) clients.splice(clients.indexOf(client.id))
})
module.exports = {
oscInFilter: function (data) {
var { address, args, host, port } = data
if (args[1].value === myClientId) {
receive(data.address, args[0], { clientId: myClientId })
console.log(args[1].value)
return // empty return to prevent the original message from passing through
}
},
oscOutFilter: function (data) {
data.args.push({
type: 's',
value: data.clientId
})
return data
}
}
I get the variable from app.on('open') method which is before module exports... What happens currently is that the myClientId
variable is overwritten by the most recent client to connect, obviously... I don't understand how to get that variable inside the module.exports block (am I right to think I need to get the var there?) - in other words, how do I get single_client_id
?
Well from what i understand you only use clientId to recognize which client initiated the request at the end of the roundtrip so actually you don't need to do any bookkeeping, all you need is to be able to read the id you inserted yourself in outgoing messages when they come back from unreal. A simple approach would be to make the id more easy to recognize:
oscOutFilter: function (data) {
data.args.push({
type: 's',
value: 'clientId:' + data.clientId
})
return data
}
And then check for its presence in incoming messages and parse it:
oscInFilter: function (data) {
var { address, args, host, port } = data
var lastArg = args[args.length - 1] // check last arg instead of 2nd (since id is pushed after any other arg)
if (lastArg.type === 's' && lastArg.value.startsWith('clientId:')) {
var id = lastArg.substr(9) // get client id (strip out prefix)
args.pop() // remove clientId from original args array
receive(data.address, ...args, {clientId: id})
console.log(args[1].value)
return // empty return to prevent the original message from passing through
}
return data // keep default return for other messages without client id arg ?
},
Hey Jean-Emmanuel sorry it took me a few days to get to this, and thank you, this helped me so much! I was missing the obvious thing which was to put oscOutFilter before oscInFilter... here's a screenshot, let me know if you'd like to see some video of this... I will post more updates as I progress with it... thanks again!
Glad you made it work ! Just to clarify: the order of the declarations within the module.exports
object is not important.