net.zortrium.p2proto
Class PeerListener

java.lang.Object
  extended by net.zortrium.p2proto.PeerListener
All Implemented Interfaces:
Runnable

public abstract class PeerListener
extends Object
implements Runnable

Listens for connections from other hosts, then spawns a thread to handle communication with each connecting host. This enables other peers to connect to this peer by creating Connection objects. Typically, applications will start a listener on startup to listen for peers, like so:

 PeerListener listener = new MyAppListener();
 new Thread(listener).start();
 
Received messages are handled via handleMessage(Msg, MsgResponder), which must be defined in the subclass. For encapsulated protocol buffer messages, a straightforward pattern for the handler implementation is to switch on the message type, then parse the encapsulated message based on the type. An example implementation following this pattern is shown below:
 
 
 private static final int MY_APP_PORT = 12345;
 
 private static final int PING_MESSAGE = 1;
 
 private static final int QUERY_MESSAGE = 2;
 
 // ... other message types ...
 
 private class MyAppListener extends PeerListener {
 
   public MyAppListener() {
     super(MY_APP_PORT);
   }
 
   public void handleMessage(Msg msg, MessageResponder responder) {
     int messageType = msg.getType();
     switch (messageType) {
       case PING_MESSAGE:
         // in this example, PingMessage is a protocol buffer message class
         PingMessage pingMsg = PingMessage.parseFrom(msg.getContent());
         handlePingMessage(pingMsg);
         break;
       case QUERY_MESSAGE:
         // QueryMessage is another protocol buffer message class
         QueryMessage joinMsg = JoinMessage.parseFrom(msg.getContent());
         handleQueryMessage(joinMsg, responder);
         break;
       // ... other message types ...
       default:
         System.err.println("unknown message type " + messageType);
         break;
     }
   }
 
   private void handlePingMessage(PingMessage ping) {
     // ... do something with ping message ...
   }
 
   private void handleQueryMessage(QueryMessage query, MessageResponder responder) {
     // ... do something with query message ...
     // send a response message back to the sender
     responder.sendResponse(myResponseMsg);
   }
 
   // ... other handler methods ...
 
 }
 
For a tutorial on defining protocol buffers messages in Java, see Protocol Buffer Basics: Java.

Author:
Sean Barker - www.zortrium.net
See Also:
Msg, MsgResponder

Constructor Summary
PeerListener(int port)
          Set up a listener for incoming connections on the given port.
PeerListener(int port, int backlog)
          Set up a listener for incoming connections on the given port.
PeerListener(int port, int backlog, InetAddress bindAddr)
          Set up a listener for incoming connections on the given port.
 
Method Summary
 void close()
          Shuts down the listener.
 int getLocalPort()
          Get the port to which the listener is bound.
abstract  void handleMessage(Msg msg, MsgResponder responder)
          Handle the message and possibly send a response or error message.
 boolean isClosed()
          Get whether the listener has been closed.
 void killConnections()
          Immediately closes all connections that are currently open.
 void run()
          Listens for incoming connections from other peers.
 void shutdown()
          Alias for close().
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PeerListener

public PeerListener(int port)
             throws IOException
Set up a listener for incoming connections on the given port. Just a wrapper to ServerSocket.ServerSocket(int).

Parameters:
port - The port to listen on.
Throws:
IOException - If an error occurs setting up the listener.

PeerListener

public PeerListener(int port,
                    int backlog)
             throws IOException
Set up a listener for incoming connections on the given port. Just a wrapper to ServerSocket.ServerSocket(int, int).

Parameters:
port - The port to listen on.
backlog - The size of the connection backlog.
Throws:
IOException - If an error occurs setting up the listener.

PeerListener

public PeerListener(int port,
                    int backlog,
                    InetAddress bindAddr)
             throws IOException
Set up a listener for incoming connections on the given port. Just a wrapper to ServerSocket.ServerSocket(int, int, InetAddress).

Parameters:
port - The port to listen on.
backlog - The size of the connection backlog.
bindAddr - The local address to bind to.
Throws:
IOException - If an error occurs setting up the listener.
Method Detail

getLocalPort

public int getLocalPort()
Get the port to which the listener is bound.

Returns:
The local port number or -1 if unbound.

handleMessage

public abstract void handleMessage(Msg msg,
                                   MsgResponder responder)
Handle the message and possibly send a response or error message. All messages have a numeric type (accessed by Msg.getType()), but may not have any content (accessed by Msg.getContent()). The passed MsgResponder allows sending a response or error message, and also identifies the source of the message via MsgResponder.getPeerAddress(). Note that there is no requirement to send any response at all (except as defined by the application).

Since this method is called for every message that arrives, there may be many threads at once within the method. As such, be very careful with any synchronization or thread-sensitive operations that are performed within. For example, putting a synchronization block around the entire method body would be extremely bad for performance, since only one message would be processed at a time.

Parameters:
msg - The received message.
responder - Used to send a response message (if needed).

run

public final void run()
Listens for incoming connections from other peers. Newly established connections are immediately handed off to worker threads, while the listener continues to wait for new connections.

Specified by:
run in interface Runnable

close

public final void close()
                 throws IOException
Shuts down the listener. No new connections will be accepted. Does not close existing connections that are already open.

Throws:
IOException - If a socket error occurs.

shutdown

public final void shutdown()
                    throws IOException
Alias for close().

Throws:
IOException

isClosed

public final boolean isClosed()
Get whether the listener has been closed.

Returns:
True if the listener has been closed.

killConnections

public final void killConnections()
Immediately closes all connections that are currently open. Currently active communications will be aborted. Does NOT shut down the listener.