hoijui / JavaOSC

OSC content format/"protocol" library for JVM languages
http://www.illposed.com/software/javaosc.html
BSD 3-Clause "New" or "Revised" License
156 stars 43 forks source link

couldn't receive message by adress #41

Closed xmr98 closed 5 years ago

xmr98 commented 5 years ago

hello,I want to receive some message by address but I can't receive it by what you write in "OSCPortln.java" :

 OSCPortIn receiver = new OSCPortIn(OSCPort.DEFAULT_SC_OSC_PORT);
  OSCMessageListener listener = new OSCMessageListener() {
  public void acceptMessage(OSCTimeStamp time, OSCMessage message) {
     System.out.println("Message received!");
   }
  };
  MessageSelector selector = new OSCPatternAddressMessageSelector(
     "/sensors");
 receiver.getDispatcher().addListener(selector, listener);
 receiver.startListening();

but I can receive message when use python code:

import argparse
import math

from pythonosc import dispatcher
from pythonosc import osc_server

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument("--ip", default="0.0.0.0", help="The ip to listen on")
  parser.add_argument("--port",
      type=int, default=8000, help="The port to listen on")
  args = parser.parse_args()

  dispatcher = dispatcher.Dispatcher()
#  dispatcher.map("/sensors", print)
  dispatcher.map("/quaternion", print)
#  dispatcher.map("/battery", print)

  server = osc_server.ThreadingOSCUDPServer(
      (args.ip, args.port), dispatcher)
  print("Serving on {}".format(server.server_address))
  server.serve_forever()

Is there something wrong with my code?

hoijui commented 5 years ago

in your java code you are litening on the port OSCPort.DEFAULT_SC_OSC_PORT which is 57110, while in your python code you ar elistening on the port 8000. If that does not help, then you might also have ot set the receiving IP address.

xmr98 commented 5 years ago

Thanks for your reply.I do set the port 8000 and in this code I forget to change that.In fact I can receive the packet through OSCPacketListener.But I can't receive message information when I use above code

hoijui commented 5 years ago

I would say this tests what you are trying to do, and it passes: https://github.com/hoijui/JavaOSC/blob/master/modules/core/src/test/java/com/illposed/osc/transport/udp/OSCPortTest.java#L482

If you can prepare a minimal example that I could execute aswell, then I could have a look, but I am pretty sure the problem in this case does not lie within JavaOSC.

xmr98 commented 5 years ago

tks we have find the problem. we do not set right ip address.are there some methods to set the OSCPortLn with ip and port?

hoijui commented 5 years ago

ook, perfect! :-) ... and yes, OSCPortIn has many constructors that take SocketAddresses, which are a combination of an IP and a port.

xmr98 commented 5 years ago

by setting right address now I can receive right packets form remote. But I still don't receive the message in the messagelistener. here is my code :

    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                SocketAddress socketAddress = new InetSocketAddress("192.168.1.2",8001) ;
                receiver = new OSCPortIn(socketAddress);
                //SocketAddress socketAddress1 = receiver.getRemoteAddress();
                MessageSelector messageSelector = new OSCPatternAddressMessageSelector("/sensors");
                OSCMessageListener messageListener = new OSCMessageListener() {

                    @Override
                    public void acceptMessage(OSCMessageEvent arg0) {
                        // TODO Auto-generated method stub
                        System.out.println("message recieved");
                    }
                };
                OSCPacketListener listener = new OSCPacketListener() {

                    @Override
                    public void handlePacket(OSCPacketEvent arg0) {
                        // TODO Auto-generated method stub
                        System.out.println("recieved");
                        System.out.println(arg0.getSource().toString());
                        System.out.println(arg0.getPacket().toString());
                    }

                    @Override
                    public void handleBadData(OSCBadDataEvent arg0) {
                        // TODO Auto-generated method stub

                    }
                };

                receiver.getDispatcher().addListener(messageSelector, messageListener);
                receiver.addPacketListener(listener);
                receiver.startListening();
                if (receiver.isListening())
                    System.out.println("Server is listening");
                receiver.run();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("error " + e);
            }
        }
    };

    thread.start();

and this is what i received

WeChat286bb678d1878a2edbe755374225539f

It is so strange!

xmr98 commented 5 years ago

btw, what i will received is a combination of messages.So should I use that Class EchoMessageListener

hoijui commented 5 years ago

I just wrote a unit test which test this scenario: https://github.com/hoijui/JavaOSC/commit/2e69a7a5d048c48857 it passes. I assume the message you are receiving does not have the address "/sensors". Try printing out the address of the received message in the packet receiver.

xmr98 commented 5 years ago

are there some example to get the message address from packets?

hoijui commented 5 years ago

use an IDE (I use IDEA, other popular ones are Eclipse and NetBeans), and work on your project in there. It makes live much easier, showing you lists of methods and so on. you will easily find it.. this is a good opportunity to learn. hint: packets have no addresses, messages have. packets contian messages.

xmr98 commented 5 years ago

Finally i got it! let me have a solution (T_T) : 1.I use the javaosc.jar packet so I can't get some private attributions for debug 2.eclipse is not a well ide for this project(because I'm not fimilar with maven so it is sadness to have some config about maven in eclipse). when i change to idea.everything changed! 3.the reason why i can't get right message is the timestamp from device!

屏幕快照 2019-04-18 下午1 14 22

It is a wrong time! so in the follow code. the dispacter will not enter mothod dispachMessageNow

屏幕快照 2019-04-18 下午1 15 24

I change the isAlwaysDispatchingImmediately() into true,and now I got the right message!!!!!!!! 4.ths for author's help.I have trapped in this problem for a long time (T_T).So it's necessary to debug the src!

hoijui commented 5 years ago

ouh wow.. very good find, congrats @xritian ! :-) hmm... I can see how this could be a problem other users would run into aswell... before the latest JavaOSC release, messages were always dispatched immediately. now, to adhere to the OSC standard, they are dispatched at the time they are specified ot be detached. so while being correct, it might not be practical in practise. :/

Possible workarounds/solutions:

I somehow like the queuedMessage(OSCMessageEvent event) idea.

daveyarwood commented 5 years ago

My 2¢: if the time tag is wrong, then that is the real issue and the only thing we should do is fix the bug.

before the latest JavaOSC release, messages were always dispatched immediately. now, to adhere to the OSC standard, they are dispatched at the time they are specified ot be detached. so while being correct, it might not be practical in practise. :/

Possible workarounds/solutions:

...

  • ignore the standard, and switch to isAlwaysDispatchingImmediately set to false again by default

I think the current behavior is fine, we just have to be very clear in our documentation that we respect the time tags and dispatch at the specified time, and if you want immediate dispatch instead, you have to set isAlwaysDispatchingImmediately to true.

  • add a new method to OSCMessageListener : messageReceived(OSCMessageEvent event), which is always triggered on recipt of a message, even if the message is going to be dispatched later on. htat way, the listener would get each matching message two timee: once in messageReceived(OSCMessageEvent event), and once in acceptMessage(OSCMessageEvent event)

I think that would be more confusing, particularly because you can already get immediate dispatch by setting isAlwaysDispatchingImmediately to true.

  • add a new method to OSCMessageListener : queuedMessage(OSCMessageEvent event), which is only when a matching, received message is not triggered immediately

I think this would lead to more complexity than we want. I think the desired workflow is that messages come in and you either want to handle them immediately, or you want to handle them at the time tag specified on the bundle. The current version of JavaOSC supports this in that you can set isAlwaysDispatchingImmediately according to the needs of your application.

Maybe I'm missing something... is there something that you can't do currently that you would be able to do if we added a queuedMessage method?

hoijui commented 5 years ago

thanks a lot @daveyarwood ; you are totally right! I improved docuemntation aroudn this issue: https://github.com/hoijui/JavaOSC/commit/f59c7592ca482b1bed7b336cc08e22ebd12c3d2e#diff-6dec594adcddc0e0cad5d68f4e4d6f54 This is where @xritian had his sample code from, so that should have heped him if it had been there already.