Closed samaaron closed 5 years ago
How is this any different than instantiating a client object like this and then sending a message?
client = OSC::Client.new( "127.0.0.1", 6555 )
client.send( OSC::Message.new( "/notify" , "1" ))
Hi @aberant,
How would you handle bidirectional comms via your approach? It's very typical for OSC servers to reply by sending messages back via the channel it received something. The approach I took was to create a server which listens for these replies and then added client abilities so it could send messages (in order to receive replies). Do you see an alternative approach?
@samaaron, I'm confused here, because you are specifying a different port for the client which leads me to believe they aren't the same socket.
can you provide me with an example of the supercollider app you are interfacing with so i can test my approach?
As far as I understood, the client port is the port the remote endpoint is listening on. My understanding of these things isn't completely 100%, so I'm happy to be educated!
I'm just interfacing with a vanilla SuperCollider server. Just start it up and fire messages at it. In my case the SuperCollider server was listening on port 6555.
As far as I understand it, all UDP packets have a source port and destination port as part of their header. For clients just firing out UDP packets, the source port is either 0 or an ephemeral port number - these packets are essentially one way as it's impossible to reply back to them. If the source port has been bound to and is listened to, then that may be used by the server receiving the UDP packet to reply back to. By explicitly creating an OSC server and using that to send the messages, this correctly sets the source port of the outgoing UDP packet to that of the OSC server, which can be used to read replies to that packet.
I've never programmed in SuperCollider, so i'm not sure what a vanilla server is. If I can get this code, it would give me a greater understanding of your use case.
There's no need to program any SuperCollider - just start the server from the command line :-)
scsynth -u 4555
let me mess with this a bit.. i'll probably have something by this weekend
okay.. so i learned a bit about scsynth and how it uses /notify and the udp source port problem. let me think up a solution to this.
so here's an example of what i'm thinking. In my idea, i've got a new client class that also accepts a socket that the server provides. BiDirectionalClient is pretty wordy, any ideas on a better name?
https://github.com/aberant/osc-ruby/compare/client_can_accept_socket
Why the need to create a separate class?
I tried putting the "optional socket argument" in the OSC::Client class, but wasn't happy with all the conditionals i needed in that class if a socket was passed in or not. Typically, numerous conditionals mean i'm trying to do too much with one class.
I still don't understand why you can't just treat a server as a client. UDP makes no such distinction. I think adding a send
method to the Server
class is far cleaner.
UDP makes no such distinction
Right, but these client/server classes here are operating at the OSC abstraction level not UDP. I want to keep the client/server jobs distinct at the OSC level.
I'm in the middle of an OSC1.1 spike where i have to support transports such as TCP and SLIP in addition to UDP. At such point, i'll have a better abstraction for a communication channel that i can pass around, that isn't just a plain socket object. I'll probably have even more clients then, depending on the transport mechanism. It probably means i'll need to create some sort of factory to simplify client creation, but i'm getting ahead of myself here.
aberant i tried your additions to osc-ruby as it seems like exactly what I need, and while it is fixing the sending port which is what i need it appears to alter the message encoding, when i compare it to the original OSC::Message send i get different packet results and only the old version returns data from the endpoint. Any advice?
Apologies, i found the issue it was me missing something.
This essentially allows the server to act as a client. This is extremely useful in the situations where you wish to send a message to an external OSC server and then listen to responses from it (which it sends back down the UDPSocket).
For example, when communicating with the SuperCollider server, it's useful to send the "/notify" command, which then allows you to receive information from the server.