Class OSCServer

  • All Implemented Interfaces:
    OSCBidi, OSCChannel

    public abstract class OSCServer
    extends Object
    implements OSCBidi
    This class dynamically groups together a transmitters and receivers, allowing bidirectional OSC communication from the perspective of a server. It simplifies the need to use several objects by uniting their functionality, and by automatically establishing child connections.

    In UDP mode, simply one receiver and transmitter are handling all the communication. In TCP mode, a ServerSocketChannel is set up to wait for incoming connection requests. Requests are satisfied by opening a new receiver and transmitter for each connection.

    In the following example, a simple TCP server is created that accepts connections at port 0x5454. The connections understand the OSC commands /pause (disconnect the server for a few seconds), /quit (quit the server), and /dumpOSC (turn on/off printing of message traffic). Each incoming message is replied with a /done message.

        private boolean pause = false; // (must be an instance or static field to be useable
                                       // from an anonymous inner class)
     
        final Object    sync = new Object();
        final OSCServer c;
        try {
            // create TCP server on loopback port 0x5454
            c = OSCServer.newUsing( OSCServer.TCP, 0x5454, true );
        }
        catch( IOException e1 ) {
            e1.printStackTrace();
            return;
        }
        
        // now add a listener for incoming messages from
        // any of the active connections
        c.addOSCListener( new OSCListener() {
            public void messageReceived( OSCMessage m, SocketAddress addr, long time )
            {
                // first of all, send a reply message (just a demo)
                try {
                    c.send( new OSCMessage( "/done", new Object[] { m.getName() }), addr );
                }
                catch( IOException e1 ) {
                    e1.printStackTrace();
                }
            
                if( m.getName().equals( "/pause" )) {
                    // tell the main thread to pause the server,
                    // wake up the main thread
                    pause = true;
                    synchronized( sync ) {
                        sync.notifyAll();
                    }
                } else if( m.getName().equals( "/quit" )) {
                    // wake up the main thread
                    synchronized( sync ) {
                        sync.notifyAll();
                    }
                } else if( m.getName().equals( "/dumpOSC" )) {
                    // change dumping behaviour
                    c.dumpOSC( ((Number) m.getArg( 0 )).intValue(), System.err );
                }
            }
        });
        try {
            do {
                if( pause ) {
                    System.out.println( "  waiting four seconds..." );
                    try {
                        Thread.sleep( 4000 );
                    }
                    catch( InterruptedException e1 ) {}
                    pause = false;
                }
                System.out.println( "  start()" );
                            // start the server (make it attentive for incoming connection requests)
                c.start();
                try {
                    synchronized( sync ) {
                        sync.wait();
                    }
                }
                catch( InterruptedException e1 ) {}
    
                System.out.println( "  stop()" );
                c.stop();
            } while( pause );
        }
        catch( IOException e1 ) {
            e1.printStackTrace();
        }
        
        // kill the server, free its resources
        c.dispose();
            
    Here is an example of sending commands to this server from SuperCollider:
        n = NetAddr( "127.0.0.1", 0x5454 );
        r = OSCresponderNode( n, '/done', { arg time, resp, msg;
            ("reply : " ++ msg.asString).postln;
        }).add;
        n.connect;
        n.sendMsg( '/dumpOSC', 3 );
        n.sendMsg( '/pause' );
        n.isConnected;      // --> false
        n.connect;
        n.sendMsg( '/quit' );
        r.remove;
            
    Since:
    NetUtil 0.30
    Version:
    0.37, 12-May-09
    Author:
    Hanns Holger Rutz
    See Also:
    OSCClient
    • Method Detail

      • newUsing

        public static OSCServer newUsing​(String protocol)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server
        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 OSCServer newUsing​(OSCPacketCodec c,
                                         String protocol)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server
        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 OSCServer newUsing​(String protocol,
                                         int port)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server listens and from which it sends, or in the case of TCP transport, from which it establishes client connections), it does not determine the remote sockets. The address of a remote client communicating to this server is passed in the messageReceived method of any registered OSCListener, and must be picked up and handed in to the send method to reply back to the client!

        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 server
        Throws:
        IOException - if a networking error occurs while creating the socket
        IllegalArgumentException - if an illegal protocol is used
      • newUsing

        public static OSCServer newUsing​(OSCPacketCodec c,
                                         String protocol,
                                         int port)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server listens and from which it sends, or in the case of TCP transport, from which it establishes client connections), it does not determine the remote sockets. The address of a remote client communicating to this server is passed in the messageReceived method of any registered OSCListener, and must be picked up and handed in to the send method to reply back to the client!

        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 server
        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 OSCServer newUsing​(String protocol,
                                         int port,
                                         boolean loopBack)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server listens and from which it sends, or in the case of TCP transport, from which it establishes client connections), it does not determine the remote sockets. The address of a remote client communicating to this server is passed in the messageReceived method of any registered OSCListener, and must be picked up and handed in to the send method to reply back to the client!

        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 server
        Throws:
        IOException - if a networking error occurs while creating the socket
        IllegalArgumentException - if an illegal protocol is used
      • newUsing

        public static OSCServer newUsing​(OSCPacketCodec c,
                                         String protocol,
                                         int port,
                                         boolean loopBack)
                                  throws IOException
        Creates a new instance of an OSCServer, 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 server listens and from which it sends, or in the case of TCP transport, from which it establishes client connections), it does not determine the remote sockets. The address of a remote client communicating to this server is passed in the messageReceived method of any registered OSCListener, and must be picked up and handed in to the send method to reply back to the client!

        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 server
        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 OSCServer newUsing​(String protocol,
                                         InetSocketAddress localAddress)
                                  throws IOException
        Creates a new instance of an OSCServer, using default codec and a specific transport protocol and local socket address.
        Parameters:
        protocol - the protocol to use, currently either UDP or TCP
        localAddress - a valid address to use for the OSC socket. If the port is 0, an arbitrary free port is picked when the receiver is started. (you can find out the actual port in this case by calling getLocalAddress() after the server was started).
        Returns:
        the newly created server
        Throws:
        IOException - if a networking error occurs while creating the socket
        IllegalArgumentException - if an illegal protocol is used
        Since:
        NetUtil 0.39
        See Also:
        OSCChannel.UDP, OSCChannel.TCP, getLocalAddress()
      • newUsing

        public static OSCServer newUsing​(OSCPacketCodec c,
                                         String protocol,
                                         InetSocketAddress localAddress)
                                  throws IOException
        Creates a new instance of an OSCServer, using a given codec, a specific transport protocol and local socket address.
        Parameters:
        c - the codec to use
        protocol - the protocol to use, currently either UDP or TCP
        localAddress - a valid address to use for the OSC socket. If the port is 0, an arbitrary free port is picked when the receiver is started. (you can find out the actual port in this case by calling getLocalAddress() after the server was started).
        Returns:
        the newly created server
        Throws:
        IOException - if a networking error occurs while creating the socket
        IllegalArgumentException - if an illegal protocol is used
        Since:
        NetUtil 0.39
        See Also:
        OSCChannel.UDP, OSCChannel.TCP, getLocalAddress()
      • getLocalAddress

        public abstract InetSocketAddress getLocalAddress()
                                                   throws IOException
        Queries the server socket's address. This is the address at which the server accepts connections (when using TCP) or receives and sends messages (when using UDP). 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 server 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 server's local socket.
        Throws:
        IOException - if the local host could not be resolved
        See Also:
        InetSocketAddress.getHostName(), InetSocketAddress.getAddress(), InetSocketAddress.getPort(), getProtocol()
      • send

        public abstract void send​(OSCPacket p,
                                  SocketAddress target)
                           throws IOException
        Sends an OSC packet (bundle or message) to the given network address. The address should correspond to one of the connected clients. Particularly, in TCP mode, trying to send to a client which is not connected will throw an exception. In a future version of NetUtil, there will be an interface to detect clients connecting and disconnecting. For now, clients can be implicitly detected by a registered OSCListener.
        Parameters:
        p - the packet to send
        target - the target address to send the packet to
        Throws:
        IOException - if a write error, OSC encoding error, buffer overflow error or network error occurs, if no client connection for the given address exists
      • addOSCListener

        public abstract void addOSCListener​(OSCListener listener)
        Registers a listener that gets informed about incoming messages (from any of the connected clients). You can call this both when the server is active or inactive.
        Parameters:
        listener - the listener to register
      • removeOSCListener

        public abstract 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 abstract void start()
                            throws IOException
        Starts the server. The server becomes attentive to requests for connections from clients, starts to receive OSC messages and is able to reply back to connected clients.
        Specified by:
        start in interface OSCBidi
        Throws:
        IOException - if a networking error occurs
      • isActive

        public abstract boolean isActive()
        Checks whether the server is active (was started) or not (is stopped).
        Specified by:
        isActive in interface OSCBidi
        Returns:
        true if the server is active, false otherwise
      • stop

        public abstract void stop()
                           throws IOException
        Stops the server. For TCP mode, this implies that all client connections are closed. Stops listening for incoming OSC traffic.
        Specified by:
        stop in interface OSCBidi
        Throws:
        IOException - if a networking error occurs
      • setBufferSize

        public abstract void setBufferSize​(int size)
        Description copied from interface: OSCChannel
        Adjusts the buffer size for OSC messages. This is the maximum size an OSC packet (bundle or message) can grow to.
        Specified by:
        setBufferSize in interface OSCChannel
        Parameters:
        size - the new size in bytes.
        See Also:
        OSCChannel.getBufferSize()
      • getBufferSize

        public abstract int getBufferSize()
        Description copied from interface: OSCChannel
        Queries the buffer size used for coding or decoding OSC messages. This is the maximum size an OSC packet (bundle or message) can grow to.
        Specified by:
        getBufferSize in interface OSCChannel
        Returns:
        the buffer size in bytes.
        See Also:
        OSCChannel.setBufferSize( int )
      • 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
      • setCodec

        public abstract void setCodec​(OSCPacketCodec c,
                                      SocketAddress target)
                               throws IOException
        Specifies which codec is used in packet coding and decoding for a given client socket.
        Parameters:
        c - the codec to use
        target - the client's address for whom the codec is changed
        Throws:
        IOException - if a networking error occurs or the client does not exist
        Since:
        NetUtil 0.33
      • getCodec

        public abstract OSCPacketCodec getCodec​(SocketAddress target)
                                         throws IOException
        Queries the codec used in packet coding and decoding for a given client socket.
        Parameters:
        target - the client's address for whom the codec is queried
        Returns:
        the current codec of this channel
        Throws:
        IOException - if a networking error occurs or the client does not exist
        Since:
        NetUtil 0.33
        See Also:
        OSCPacketCodec.getDefaultCodec()
      • dumpOSC

        public final void dumpOSC​(int mode,
                                  PrintStream stream)
        Description copied from interface: OSCChannel
        Changes the way processed 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:
        OSCChannel.kDumpOff, OSCChannel.kDumpText, OSCChannel.kDumpHex, OSCChannel.kDumpBoth
      • dumpIncomingOSC

        public abstract 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 )
      • dispose

        public abstract void dispose()
        Destroys the server and frees resources associated with it. This automatically stops the server and closes the networking channels. Do not use this server instance any more after calling dispose.
        Specified by:
        dispose in interface OSCChannel