python-osc
python-osc copied to clipboard
OSC server unable to listen to multicast messages from Liblo (?)
Hello,
I'm looking to replace PyLiblo in my project with your module, but it seems not to be able to listen to messages created by a C binary using Liblo.
Both the Python process and the C process create a client and a server to communicate. The python-osc client can successfully send a message to the C Liblo server, but it seems that all messages originating from the C client (using lo_address) are dropped. From the research I've done, this seems to be related to Liblo using multicast messages, which are not compatible with Python's socketserver module. I did confirm that both were using UDP on the same port, and tried various permutations of "localhost", "127.0.0.1" and "0.0.0.0" for both client and server, as well as the blocking, threading and forking servers.
I did find some literature about making socketserver listen to multicast messages (it's Python2 code, but should be easily ported to Python3):
http://www.nealc.com/blog/blog/2012/09/11/testing/
Hi and thanks for catching that issue, I am swamped on other projects so most probably won't have the time to work on this feature unfortunately, (I also never played with multicast before...) but I welcome pull requests! ;-)
It seems that multicast support for the standard library socketserver.UDPServer missing is a pain and could be useful for others too so perhaps making it a standalone project on github sounds like a good idea too!
Sure, I'll start working on a patch for multicast support soon (probably in the next week or so after I finish the next release of my project). :smile:
Awesome, keep me posted!
I spent some time attempting this, and unfortunately it's a much bigger task than I anticipated. Most of the problems are with:
mreq = struct.pack("4sI", socket.inet_aton(multicast_address[0]),
socket.INADDR_ANY)
self.socket.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP, mreq)
which doesn't work reliably without specifying a network interface (even if running the same OS on 2 different machines). Unfortunately, Python doesn't offer a cross-platform way to enumerate network interfaces.
I studied LibLo's source code to see how they do it, and it should be possible to emulate what they did in pure Python using socket and setsockopt, etc... but that would be a huge task to recreate everything they've done, and it would probably make sense to completely drop socketserver and write a custom server class, which would be a fairly radical and invasive change to python-osc. It would probably be much easier for the LibLo folks to create a new constructor for lo_address that doesn't use multicast in send_data(...).
Unfortunately, this would probably take me 1-2 weeks to implement, and I don't currently have that much free time to work on this. I wanted to post my notes here in case somebody else wants to work on this (or petition the LibLo folks to allow non-multicast lo_address)
Thanks for having a try at this! I hope the LibLo folks allow their Io_address to not use multicast in the near future. Might be worth filing a but to them if you feel like it.
Hi, Did you take time to work on multicast listener ?
Maybe worth mentioning @radarsat1 for this one, to join in on the conversation.