Allow the connection manager to listen for incoming connections on
multiple ports. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3655 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -69,7 +69,18 @@ public class ConnectionManager extends LoopingThread
|
|||||||
public ConnectionManager (int port)
|
public ConnectionManager (int port)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
_port = port;
|
this(new int[] { port });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs and initialized a connection manager (binding socket on
|
||||||
|
* which it will listen for client connections to each of the
|
||||||
|
* specified ports).
|
||||||
|
*/
|
||||||
|
public ConnectionManager (int[] ports)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
_ports = ports;
|
||||||
_selector = SelectorProvider.provider().openSelector();
|
_selector = SelectorProvider.provider().openSelector();
|
||||||
|
|
||||||
// create our stats record
|
// create our stats record
|
||||||
@@ -249,38 +260,47 @@ public class ConnectionManager extends LoopingThread
|
|||||||
// documentation inherited
|
// documentation inherited
|
||||||
protected void willStart ()
|
protected void willStart ()
|
||||||
{
|
{
|
||||||
try {
|
int successes = 0;
|
||||||
// create our listening socket and add it to the select set
|
IOException _failure = null;
|
||||||
_listener = ServerSocketChannel.open();
|
for (int ii = 0; ii < _ports.length; ii++) {
|
||||||
_listener.configureBlocking(false);
|
try {
|
||||||
|
// create a listening socket and add it to the select set
|
||||||
|
final ServerSocketChannel listener = ServerSocketChannel.open();
|
||||||
|
listener.configureBlocking(false);
|
||||||
|
|
||||||
InetSocketAddress isa = new InetSocketAddress(_port);
|
InetSocketAddress isa = new InetSocketAddress(_ports[ii]);
|
||||||
_listener.socket().bind(isa);
|
listener.socket().bind(isa);
|
||||||
Log.info("Server listening on " + isa + ".");
|
Log.info("Server listening on " + isa + ".");
|
||||||
|
|
||||||
// register our listening socket and map its select key to a
|
// register this listening socket and map its select key
|
||||||
// net event handler that will accept new connections
|
// to a net event handler that will accept new connections
|
||||||
SelectionKey lkey =
|
SelectionKey lkey =
|
||||||
_listener.register(_selector, SelectionKey.OP_ACCEPT);
|
listener.register(_selector, SelectionKey.OP_ACCEPT);
|
||||||
_handlers.put(lkey, new NetEventHandler() {
|
_handlers.put(lkey, new NetEventHandler() {
|
||||||
public int handleEvent (long when) {
|
public int handleEvent (long when) {
|
||||||
acceptConnection();
|
acceptConnection(listener);
|
||||||
// there's no easy way to measure bytes read when
|
// there's no easy way to measure bytes read when
|
||||||
// accepting a connection, so we claim nothing
|
// accepting a connection, so we claim nothing
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public boolean checkIdle (long now) {
|
public boolean checkIdle (long now) {
|
||||||
return false; // we're never idle
|
return false; // we're never idle
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
successes++;
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Failure listening to socket on port '" +_port + "'.");
|
Log.warning("Failure listening to socket on " +
|
||||||
Log.logStackTrace(ioe);
|
"port '" +_ports[ii] + "'.");
|
||||||
|
Log.logStackTrace(ioe);
|
||||||
|
_failure = ioe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// notify our startup listener, if we have one
|
// if we failed to listen on at least one port, give up the ghost
|
||||||
|
if (successes == 0) {
|
||||||
if (_startlist != null) {
|
if (_startlist != null) {
|
||||||
_startlist.requestFailed(ioe);
|
_startlist.requestFailed(_failure);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -588,12 +608,12 @@ public class ConnectionManager extends LoopingThread
|
|||||||
* Called by our net event handler when a new connection is ready to
|
* Called by our net event handler when a new connection is ready to
|
||||||
* be accepted on our listening socket.
|
* be accepted on our listening socket.
|
||||||
*/
|
*/
|
||||||
protected void acceptConnection ()
|
protected void acceptConnection (ServerSocketChannel listener)
|
||||||
{
|
{
|
||||||
SocketChannel channel = null;
|
SocketChannel channel = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
channel = _listener.accept();
|
channel = listener.accept();
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
// in theory this shouldn't happen because we got an
|
// in theory this shouldn't happen because we got an
|
||||||
// ACCEPT_READY event, but better safe than sorry
|
// ACCEPT_READY event, but better safe than sorry
|
||||||
@@ -817,10 +837,9 @@ public class ConnectionManager extends LoopingThread
|
|||||||
protected int _msgs, _partials;
|
protected int _msgs, _partials;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int _port;
|
protected int[] _ports;
|
||||||
protected Authenticator _author;
|
protected Authenticator _author;
|
||||||
protected Selector _selector;
|
protected Selector _selector;
|
||||||
protected ServerSocketChannel _listener;
|
|
||||||
protected ResultListener _startlist;
|
protected ResultListener _startlist;
|
||||||
|
|
||||||
/** Counts consecutive runtime errors in select(). */
|
/** Counts consecutive runtime errors in select(). */
|
||||||
|
|||||||
Reference in New Issue
Block a user