de.sciss.net
Class OSCClient

java.lang.Object
  extended by de.sciss.net.OSCClient
All Implemented Interfaces:
OSCBidi, OSCChannel

public class OSCClient
extends Object
implements OSCBidi

This class groups together a transmitter and receiver, allowing bidirectional OSC communication from the perspective of a client. It simplifies the need to use several objects by uniting their functionality.

In the following example, a client for UDP to SuperCollider server (scsynth) on the local machine is created. The client starts a synth by sending a /s_new message, and stops the synth by sending a delayed a /n_set message. It waits for the synth to die which is recognized by an incoming /n_end message from scsynth after we've registered using a /notify command.

    final Object        sync = new Object();
    final OSCClient     c;
    final OSCBundle     bndl1, bndl2;
    final Integer       nodeID;

    try {
        c = OSCClient.newUsing( OSCClient.UDP );    // create UDP client with any free port number
        c.setTarget( new InetSocketAddress( "127.0.0.1", 57110 ));  // talk to scsynth on the same machine
        c.start();  // open channel and (in the case of TCP) connect, then start listening for replies
    }
    catch( IOException e1 ) {
        e1.printStackTrace();
        return;
    }

    // register a listener for incoming osc messages
    c.addOSCListener( new OSCListener() {
        public void messageReceived( OSCMessage m, SocketAddress addr, long time )
        {
            // if we get the /n_end message, wake up the main thread
            // ; note: we should better also check for the node ID to make sure
            // the message corresponds to our synth
            if( m.getName().equals( "/n_end" )) {
                synchronized( sync ) {
                    sync.notifyAll();
                }
            }
        }
    });
    // let's see what's going out and coming in
    c.dumpOSC( OSCChannel.kDumpBoth, System.err );

    try {
        // the /notify message tells scsynth to send info messages back to us
        c.send( new OSCMessage( "/notify", new Object[] { new Integer( 1 )}));
        // two bundles, one immediately (with 50ms delay), the other in 1.5 seconds
        bndl1   = new OSCBundle( System.currentTimeMillis() + 50 );
        bndl2   = new OSCBundle( System.currentTimeMillis() + 1550 );
        // this is going to be the node ID of our synth
        nodeID  = new Integer( 1001 + i );
        // this next messages creates the synth
        bndl1.addPacket( new OSCMessage( "/s_new", new Object[] { "default", nodeID, new Integer( 1 ), new Integer( 0 )}));
        // this next messages starts to releases the synth in 1.5 seconds (release time is 2 seconds)
        bndl2.addPacket( new OSCMessage( "/n_set", new Object[] { nodeID, "gate", new Float( -(2f + 1f) )}));
        // send both bundles (scsynth handles their respective timetags)
        c.send( bndl1 );
        c.send( bndl2 );

        // now wait for the signal from our osc listener (or timeout in 10 seconds)
        synchronized( sync ) {
            sync.wait( 10000 );
        }
        catch( InterruptedException e1 ) {}

        // ok, unsubscribe getting info messages
        c.send( new OSCMessage( "/notify", new Object[] { new Integer( 0 )}));

        // ok, stop the client
        // ; this isn't really necessary as we call dispose soon
        c.stop();
    }
    catch( IOException e11 ) {
        e11.printStackTrace();
    }

    // dispose the client (it gets stopped if still running)
    c.dispose();
        

Since:
NetUtil 0.30
Version:
0.37, 12-May-09
Author:
Hanns Holger Rutz
See Also:
OSCTransmitter, OSCReceiver, OSCServer

Field Summary
 
Fields inherited from interface de.sciss.net.OSCChannel
DEFAULTBUFSIZE, kDumpBoth, kDumpHex, kDumpOff, kDumpText, TCP, UDP
 
Method Summary
 void addOSCListener(OSCListener listener)
          Registers a listener that gets informed about incoming messages.
 void connect()
          Initializes network channel (if necessary) and establishes connection for transports requiring connectivity (e.g.
 void dispose()
          Destroys the client and frees resources associated with it.
 void dumpIncomingOSC(int mode, PrintStream stream)
          Changes the way incoming messages are dumped to the console.
 void dumpOSC(int mode, PrintStream stream)
          Changes the way incoming and outgoing OSC messages are printed to the standard err console.
 void dumpOutgoingOSC(int mode, PrintStream stream)
          Changes the way outgoing messages are dumped to the console.
 int getBufferSize()
          Queries the buffer size used for sending and receiving OSC messages.
 OSCPacketCodec getCodec()
          Queries the codec used in packet coding and decoding.
 InetSocketAddress getLocalAddress()
          Queries the client side socket address.
 String getProtocol()
          Queries the transport protocol used by this communicator.
 boolean isActive()
          Queries whether the client was activated or not.
 boolean isConnected()
          Queries the connection state of the client.
static OSCClient newUsing(OSCPacketCodec c, String protocol)
          Creates a new instance of an OSCClient, using a specific codec and transport protocol.
static OSCClient newUsing(OSCPacketCodec c, String protocol, InetSocketAddress localAddress)
          Creates a new instance of an OSCClient, using a given codec, a specific transport protocol and local socket address.
static OSCClient newUsing(OSCPacketCodec c, String protocol, int port)
          Creates a new instance of an OSCClient, using a specific codec and transport protocol and port.
static OSCClient newUsing(OSCPacketCodec c, String protocol, int port, boolean loopBack)
          Creates a new instance of an OSCClient, using a specific codec and transport protocol and port.
static OSCClient newUsing(String protocol)
          Creates a new instance of an OSCClient, using default codec and a specific transport protocol.
static OSCClient newUsing(String protocol, InetSocketAddress localAddress)
          Creates a new instance of an OSCClient, using default codec and a specific transport protocol and local socket address.
static OSCClient newUsing(String protocol, int port)
          Creates a new instance of an OSCClient, using default codec and a specific transport protocol and port.
static OSCClient newUsing(String protocol, int port, boolean loopBack)
          Creates a new instance of an OSCClient, using default codec and a specific transport protocol and port.
 void removeOSCListener(OSCListener listener)
          Unregisters a listener that gets informed about incoming messages
 void send(OSCPacket p)
          Sends an OSC packet (bundle or message) to the target network address.
 void setBufferSize(int size)
          Adjusts the buffer size for OSC messages (both for sending and receiving).
 void setCodec(OSCPacketCodec c)
          Specifies which codec is used in packet coding and decoding.
 void setTarget(SocketAddress target)
          Specifies the client's target address, that is the address of the server to talk to.
 void start()
          Starts the client.
 void stop()
          Stops the communicator.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

newUsing

public static OSCClient newUsing(String protocol)
                          throws IOException
Creates a new instance of an OSCClient, using default codec and a specific transport protocol. It picks an arbitrary free port and uses the local machine's IP. To determine the resulting port, you can use getLocalAddress afterwards.

Parameters:
protocol - the protocol to use, currently either UDP or TCP
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
See Also:
OSCChannel.UDP, OSCChannel.TCP, getLocalAddress()

newUsing

public static OSCClient newUsing(OSCPacketCodec c,
                                 String protocol)
                          throws IOException
Creates a new instance of an OSCClient, using a specific codec and transport protocol. It picks an arbitrary free port and uses the local machine's IP. To determine the resulting port, you can use getLocalAddress afterwards.

Parameters:
c - the codec to use
protocol - the protocol to use, currently either UDP or TCP
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
Since:
NetUtil 0.33
See Also:
OSCChannel.UDP, OSCChannel.TCP, getLocalAddress()

newUsing

public static OSCClient newUsing(String protocol,
                                 int port)
                          throws IOException
Creates a new instance of an OSCClient, using default codec and a specific transport protocol and port. It uses the local machine's IP.

Note that the port specifies the local socket (at which the client listens and from which it sends), it does not determine the remote sockets from which messages can be received and to which messages are sent. The target socket can be set using the setTarget method!

Parameters:
protocol - the protocol to use, currently either UDP or TCP
port - the port number for the OSC socket, or 0 to use an arbitrary free port
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used

newUsing

public static OSCClient newUsing(OSCPacketCodec c,
                                 String protocol,
                                 int port)
                          throws IOException
Creates a new instance of an OSCClient, using a specific codec and transport protocol and port. It uses the local machine's IP.

Note that the port specifies the local socket (at which the client listens and from which it sends), it does not determine the remote sockets from which messages can be received and to which messages are sent. The target socket can be set using the setTarget method!

Parameters:
c - the codec to use
protocol - the protocol to use, currently either UDP or TCP
port - the port number for the OSC socket, or 0 to use an arbitrary free port
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
Since:
NetUtil 0.33

newUsing

public static OSCClient newUsing(String protocol,
                                 int port,
                                 boolean loopBack)
                          throws IOException
Creates a new instance of an OSCClient, using default codec and a specific transport protocol and port. It uses the local machine's IP or the "loopback" address.

Note that the port specifies the local socket (at which the client listens and from which it sends), it does not determine the remote sockets from which messages can be received and to which messages are sent. The target socket can be set using the setTarget method!

Parameters:
protocol - the protocol to use, currently either UDP or TCP
port - the port number for the OSC socket, or 0 to use an arbitrary free port
loopBack - if true, the "loopback" address ("127.0.0.1") is used which limits communication to the local machine. If false, the special IP "0.0.0.0" is used which means messages from any IP as well as from the loopback are accepted
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used

newUsing

public static OSCClient newUsing(OSCPacketCodec c,
                                 String protocol,
                                 int port,
                                 boolean loopBack)
                          throws IOException
Creates a new instance of an OSCClient, using a specific codec and transport protocol and port. It uses the local machine's IP or the "loopback" address.

Note that the port specifies the local socket (at which the client listens and from which it sends), it does not determine the remote sockets from which messages can be received and to which messages are sent. The target socket can be set using the setTarget method!

Parameters:
c - the codec to use
protocol - the protocol to use, currently either UDP or TCP
port - the port number for the OSC socket, or 0 to use an arbitrary free port
loopBack - if true, the "loopback" address ("127.0.0.1") is used which limits communication to the local machine. If false, the special IP "0.0.0.0" is used which means messages from any IP as well as from the loopback are accepted
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
Since:
NetUtil 0.33

newUsing

public static OSCClient newUsing(String protocol,
                                 InetSocketAddress localAddress)
                          throws IOException
Creates a new instance of an OSCClient, using default codec and a specific transport protocol and local socket address. Note that localAdress specifies the local socket (at which the receiver listens and from which the transmitter sends), it does not determine the remote sockets to which the client connects. To specify the remote socket, use the setTarget method!

Parameters:
protocol - the protocol to use, currently either UDP or TCP
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
Since:
NetUtil 0.39

newUsing

public static OSCClient newUsing(OSCPacketCodec c,
                                 String protocol,
                                 InetSocketAddress localAddress)
                          throws IOException
Creates a new instance of an OSCClient, using a given codec, a specific transport protocol and local socket address. Note that localAdress specifies the local socket (at which the receiver listens and from which the transmitter sends), it does not determine the remote sockets to which the client connects. To specify the remote socket, use the setTarget method!

Parameters:
c - the codec to use
protocol - the protocol to use, currently either UDP or TCP
Returns:
the newly created client
Throws:
IOException - if a networking error occurs while creating the socket
IllegalArgumentException - if an illegal protocol is used
Since:
NetUtil 0.39

getProtocol

public String getProtocol()
Description copied from interface: OSCChannel
Queries the transport protocol used by this communicator.

Specified by:
getProtocol in interface OSCChannel
Returns:
the protocol, such as UDP or TCP
See Also:
OSCChannel.UDP, OSCChannel.TCP

getLocalAddress

public InetSocketAddress getLocalAddress()
                                  throws IOException
Queries the client side socket address. This is the address from which the client sends and at which it listens for replies. You can determine the host and port from the returned address by calling getHostName() (or for the IP getAddress().getHostAddress()) and getPort().

Note that if the client is bound to the accept-any IP "0.0.0.0", which happens for example when calling newUsing( <protocol>, 0, false ), the returned IP will be the localhost's IP, so you can patch the result directly into any setTarget call.

Specified by:
getLocalAddress in interface OSCChannel
Returns:
the address of the client's local socket.
Throws:
IOException - if the local host could not be resolved
See Also:
InetSocketAddress.getHostName(), InetSocketAddress.getAddress(), InetSocketAddress.getPort(), getProtocol()

setTarget

public void setTarget(SocketAddress target)
Specifies the client's target address, that is the address of the server to talk to. You should call this method only once and you must call it before starting the client or sending messages.

Parameters:
target - the address of the server. Usually you construct an appropriate InetSocketAddress
See Also:
InetSocketAddress

setCodec

public void setCodec(OSCPacketCodec c)
Description copied from interface: OSCChannel
Specifies which codec is used in packet coding and decoding.

Specified by:
setCodec in interface OSCChannel
Parameters:
c - the codec to use

getCodec

public OSCPacketCodec getCodec()
Description copied from interface: OSCChannel
Queries the codec used in packet coding and decoding.

Specified by:
getCodec in interface OSCChannel
Returns:
the current codec of this channel
See Also:
OSCPacketCodec.getDefaultCodec()

connect

public void connect()
             throws IOException
Initializes network channel (if necessary) and establishes connection for transports requiring connectivity (e.g. TCP). Do not call this method when the client is already connected. Note that start implicitly calls connect if necessary, so usually you will not need to call connect yourself.

Throws:
IOException - if a networking error occurs. Possible reasons: - the underlying network channel had been closed by the server. - the transport is TCP and the server is not available. - the transport is TCP and the client was stopped before (unable to revive).
See Also:
isConnected(), start()

isConnected

public boolean isConnected()
Queries the connection state of the client.

Returns:
true if the client is connected, false otherwise. For transports that do not use connectivity (e.g. UDP) this returns false, if the underlying DatagramChannel has not yet been created.
See Also:
connect()

send

public void send(OSCPacket p)
          throws IOException
Sends an OSC packet (bundle or message) to the target network address. Make sure that the client's target has been specified before by calling setTarget()

Parameters:
p - the packet to send
Throws:
IOException - if a write error, OSC encoding error, buffer overflow error or network error occurs, for example if a TCP client was not connected before.
NullPointerException - for a UDP client if the target has not been specified
See Also:
setTarget( SocketAddress )

addOSCListener

public void addOSCListener(OSCListener listener)
Registers a listener that gets informed about incoming messages. You can call this both when the client is active or inactive.

Parameters:
listener - the listener to register

removeOSCListener

public void removeOSCListener(OSCListener listener)
Unregisters a listener that gets informed about incoming messages

Parameters:
listener - the listener to remove from the list of notified objects.

start

public void start()
           throws IOException
Starts the client. This calls connect if the transport requires connectivity (e.g. TCP) and the channel is not yet connected. It then tells the underlying OSC receiver to start listening.

Specified by:
start in interface OSCBidi
Throws:
IOException - if a networking error occurs. Possible reasons: - the underlying network channel had been closed by the server. - the transport is TCP and the server is not available. - the transport is TCP and the client was stopped before (unable to revive).
Warning:
in the current version, it is not possible to "revive" clients after the server has closed the connection. Also it's not possible to start a TCP client more than once. This might be possible in a future version.

isActive

public boolean isActive()
Queries whether the client was activated or not. A client is activated by calling its start() method and deactivated by calling stop().

Specified by:
isActive in interface OSCBidi
Returns:
true if the client is active (connected and listening), false otherwise.
See Also:
start(), stop()

stop

public void stop()
          throws IOException
Description copied from interface: OSCBidi
Stops the communicator.

Specified by:
stop in interface OSCBidi
Throws:
IOException - if a networking error occurs

setBufferSize

public void setBufferSize(int size)
Adjusts the buffer size for OSC messages (both for sending and receiving). This is the maximum size an OSC packet (bundle or message) can grow to. The initial buffer size is DEFAULTBUFSIZE. Do not call this method while the client is active!

Specified by:
setBufferSize in interface OSCChannel
Parameters:
size - the new size in bytes.
Throws:
IllegalStateException - if trying to change the buffer size while the client is active (listening).
See Also:
isActive(), getBufferSize()

getBufferSize

public int getBufferSize()
Queries the buffer size used for sending and receiving OSC messages. This is the maximum size an OSC packet (bundle or message) can grow to. The initial buffer size is DEFAULTBUFSIZE.

Specified by:
getBufferSize in interface OSCChannel
Returns:
the buffer size in bytes.
See Also:
setBufferSize( int )

dumpOSC

public void dumpOSC(int mode,
                    PrintStream stream)
Changes the way incoming and outgoing OSC messages are printed to the standard err console. By default messages are not printed.

Specified by:
dumpOSC in interface OSCChannel
Parameters:
mode - one of kDumpOff (don't dump, default), kDumpText (dump human readable string), kDumpHex (hexdump), or kDumpBoth (both text and hex)
stream - the stream to print on, or null which is shorthand for System.err
See Also:
dumpIncomingOSC( int, PrintStream ), dumpOutgoingOSC( int, PrintStream ), OSCChannel.kDumpOff, OSCChannel.kDumpText, OSCChannel.kDumpHex, OSCChannel.kDumpBoth

dumpIncomingOSC

public void dumpIncomingOSC(int mode,
                            PrintStream stream)
Description copied from interface: OSCBidi
Changes the way incoming messages are dumped to the console. By default incoming messages are not dumped. Incoming messages are those received by the client from the server, before they get delivered to registered OSCListeners.

Specified by:
dumpIncomingOSC in interface OSCBidi
Parameters:
mode - see dumpOSC( int ) for details
stream - the stream to print on, or null which is shorthand for System.err
See Also:
OSCChannel.dumpOSC( int, PrintStream ), OSCBidi.dumpOutgoingOSC( int, PrintStream )

dumpOutgoingOSC

public void dumpOutgoingOSC(int mode,
                            PrintStream stream)
Description copied from interface: OSCBidi
Changes the way outgoing messages are dumped to the console. By default outgoing messages are not dumped. Outgoing messages are those send via send.

Specified by:
dumpOutgoingOSC in interface OSCBidi
Parameters:
mode - see dumpOSC( int ) for details
stream - the stream to print on, or null which is shorthand for System.err
See Also:
OSCChannel.dumpOSC( int, PrintStream ), OSCBidi.dumpIncomingOSC( int, PrintStream )

dispose

public void dispose()
Destroys the client and frees resources associated with it. This automatically stops the client and closes the networking channel. Do not use this client instance any more after calling dispose.

Specified by:
dispose in interface OSCChannel