diff --git a/src/java/com/threerings/presents/server/PresentsServer.java b/src/java/com/threerings/presents/server/PresentsServer.java
index 05df9e54c..82d768b8c 100644
--- a/src/java/com/threerings/presents/server/PresentsServer.java
+++ b/src/java/com/threerings/presents/server/PresentsServer.java
@@ -157,7 +157,7 @@ public class PresentsServer
_clmgr.setInjector(injector);
// configure our connection manager
- _conmgr.init(getListenPorts(), getDatagramPorts(), getDatagramHostname());
+ _conmgr.init(getBindHostname(), getListenPorts(), getDatagramPorts());
// initialize the time base services
TimeBaseProvider.init(_invmgr, _omgr);
@@ -224,6 +224,15 @@ public class PresentsServer
return PresentsObjectAccess.DEFAULT;
}
+ /**
+ * Returns the hostname on which the connection manager will listen for TCP and datagram
+ * traffic, or null to bind to the wildcard address.
+ */
+ protected String getBindHostname ()
+ {
+ return null;
+ }
+
/**
* Returns the port on which the connection manager will listen for client connections.
*/
@@ -240,15 +249,6 @@ public class PresentsServer
return Client.DEFAULT_DATAGRAM_PORTS;
}
- /**
- * Returns the hostname for which the connection manager will listen for datagrams, or
- * null to bind to the wildcard address.
- */
- protected String getDatagramHostname ()
- {
- return null;
- }
-
/**
* Called once the invoker and distributed object manager have both completed processing all
* remaining events and are fully shutdown. Note: this is called as the last act of
diff --git a/src/java/com/threerings/presents/server/net/ConnectionManager.java b/src/java/com/threerings/presents/server/net/ConnectionManager.java
index d1ce42628..225afe41c 100644
--- a/src/java/com/threerings/presents/server/net/ConnectionManager.java
+++ b/src/java/com/threerings/presents/server/net/ConnectionManager.java
@@ -41,6 +41,7 @@ import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
@@ -53,6 +54,7 @@ import com.samskivert.util.Lifecycle;
import com.samskivert.util.LoopingThread;
import com.samskivert.util.Queue;
import com.samskivert.util.ResultListener;
+import com.samskivert.util.StringUtil;
import com.samskivert.util.Tuple;
import com.threerings.io.ByteBufferInputStream;
@@ -99,35 +101,25 @@ public class ConnectionManager extends LoopingThread
}
/**
- * Constructs and initialized a connection manager (binding socket on which it will listen for
- * client connections to each of the specified ports).
+ * Configures the connection manager with the hostname and ports on which it will listen for
+ * socket connections and datagram packets. This must be called before the connection manager
+ * is started (via {@via #start}) as the sockets will be bound at that time.
+ *
+ * @param bindHostname the port to which to bind our sockets or null to bind to all interfaces.
+ * @param ports the ports on which to listen for TCP connection.
+ * @param datagramPorts the ports on which to listen for datagram packets.
*/
- public void init (int[] ports)
+ public void init (String bindHostname, int[] ports, int[] datagramPorts)
throws IOException
{
- init(ports, new int[0]);
- }
+ Preconditions.checkArgument(ports != null, "Ports must be non-null.");
+ Preconditions.checkArgument(datagramPorts != null, "Datagram ports must be non-null. " +
+ "Pass a zero-length array to bind no datagram ports.");
+ Preconditions.checkState(!isRunning(), "Must initialize before starting.");
- /**
- * Constructs and initialized a connection manager (binding socket on which it will listen for
- * client connections to each of the specified ports).
- */
- public void init (int[] ports, int[] datagramPorts)
- throws IOException
- {
- init(ports, datagramPorts, null);
- }
-
- /**
- * Constructs and initialized a connection manager (binding socket on which it will listen for
- * client connections to each of the specified ports).
- */
- public void init (int[] ports, int[] datagramPorts, String datagramHostname)
- throws IOException
- {
+ _bindHostname = bindHostname;
_ports = ports;
_datagramPorts = datagramPorts;
- _datagramHostname = datagramHostname;
_selector = SelectorProvider.provider().openSelector();
// create our stats record
@@ -361,14 +353,15 @@ public class ConnectionManager extends LoopingThread
_ssocket = ServerSocketChannel.open();
_ssocket.configureBlocking(false);
- InetSocketAddress isa = new InetSocketAddress(port);
+ InetSocketAddress isa = getAddress(port);
_ssocket.socket().bind(isa);
registerChannel(_ssocket);
successes++;
log.info("Server listening on " + isa + ".");
} catch (IOException ioe) {
- log.warning("Failure listening to socket on port '" + port + "'.", ioe);
+ log.warning("Failure listening to socket", "hostname", _bindHostname,
+ "port", port, ioe);
}
}
@@ -411,19 +404,25 @@ public class ConnectionManager extends LoopingThread
// create a channel and add it to the select set
_datagramChannel = DatagramChannel.open();
_datagramChannel.configureBlocking(false);
-
- InetSocketAddress isa = (_datagramHostname == null) ?
- new InetSocketAddress(port) : new InetSocketAddress(_datagramHostname, port);
+ InetSocketAddress isa = getAddress(port);
_datagramChannel.socket().bind(isa);
registerChannel(_datagramChannel);
log.info("Server accepting datagrams on " + isa + ".");
} catch (IOException ioe) {
- log.warning("Failure opening datagram channel on port '" + port + "'.", ioe);
+ log.warning("Failure opening datagram channel", "hostname", _bindHostname,
+ "port", port, ioe);
}
}
}
+ /** Helper function for creating proper bindable socket addresses. */
+ protected InetSocketAddress getAddress (int port)
+ {
+ return StringUtil.isBlank(_bindHostname) ?
+ new InetSocketAddress(port) : new InetSocketAddress(_datagramHostname, port);
+ }
+
/** Helper function for {@link #willStart}. */
protected void registerChannel (final ServerSocketChannel listener)
throws IOException
@@ -1208,6 +1207,7 @@ public class ConnectionManager extends LoopingThread
protected List _authors = Lists.newArrayList();
protected int[] _ports, _datagramPorts;
+ protected String _bindHostname;
protected String _datagramHostname;
protected Selector _selector;
protected ServerSocketChannel _ssocket;