More clearly specified TCP/UDP port requirements. Code polish
This commit is contained in:
parent
c33a086465
commit
12c628bcae
@ -95,21 +95,21 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("AutoBoxing")
|
@SuppressWarnings("AutoBoxing")
|
||||||
public
|
public
|
||||||
Client(final Configuration options) throws InitializationException, SecurityException, IOException {
|
Client(final Configuration config) throws InitializationException, SecurityException, IOException {
|
||||||
super(options);
|
super(config);
|
||||||
|
|
||||||
String threadName = Client.class.getSimpleName();
|
String threadName = Client.class.getSimpleName();
|
||||||
|
|
||||||
Logger logger2 = this.logger;
|
Logger logger2 = this.logger;
|
||||||
if (options.localChannelName != null && (options.tcpPort > 0 || options.udpPort > 0 || options.host != null) ||
|
if (config.localChannelName != null && (config.tcpPort > 0 || config.udpPort > 0 || config.host != null) ||
|
||||||
options.localChannelName == null && (options.tcpPort == 0 || options.udpPort == 0 || options.host == null)) {
|
config.localChannelName == null && (config.tcpPort == 0 || config.udpPort == 0 || config.host == null)) {
|
||||||
String msg = threadName + " Local channel use and TCP/UDP use are MUTUALLY exclusive. Unable to determine intent.";
|
String msg = threadName + " Local channel use and TCP/UDP use are MUTUALLY exclusive. Unable to determine intent.";
|
||||||
logger2.error(msg);
|
logger2.error(msg);
|
||||||
throw new IllegalArgumentException(msg);
|
throw new IllegalArgumentException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
localChannelName = options.localChannelName;
|
localChannelName = config.localChannelName;
|
||||||
hostName = options.host;
|
hostName = config.host;
|
||||||
|
|
||||||
boolean isAndroid = PlatformDependent.isAndroid();
|
boolean isAndroid = PlatformDependent.isAndroid();
|
||||||
|
|
||||||
@ -130,33 +130,33 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||||||
|
|
||||||
manageForShutdown(boss);
|
manageForShutdown(boss);
|
||||||
|
|
||||||
if (options.localChannelName != null && options.tcpPort < 0 && options.udpPort < 0) {
|
if (config.localChannelName != null && config.tcpPort <= 0 && config.udpPort <= 0) {
|
||||||
// no networked bootstraps. LOCAL connection only
|
// no networked bootstraps. LOCAL connection only
|
||||||
Bootstrap localBootstrap = new Bootstrap();
|
Bootstrap localBootstrap = new Bootstrap();
|
||||||
this.bootstraps.add(new BootstrapWrapper("LOCAL", options.localChannelName, -1, localBootstrap));
|
this.bootstraps.add(new BootstrapWrapper("LOCAL", config.localChannelName, -1, localBootstrap));
|
||||||
|
|
||||||
EventLoopGroup localBoss = new DefaultEventLoopGroup(DEFAULT_THREAD_POOL_SIZE, new NamedThreadFactory(threadName + "-LOCAL",
|
EventLoopGroup localBoss = new DefaultEventLoopGroup(DEFAULT_THREAD_POOL_SIZE, new NamedThreadFactory(threadName + "-LOCAL",
|
||||||
threadGroup));
|
threadGroup));
|
||||||
|
|
||||||
localBootstrap.group(localBoss)
|
localBootstrap.group(localBoss)
|
||||||
.channel(LocalChannel.class)
|
.channel(LocalChannel.class)
|
||||||
.remoteAddress(new LocalAddress(options.localChannelName))
|
.remoteAddress(new LocalAddress(config.localChannelName))
|
||||||
.handler(new RegistrationLocalHandlerClient<C>(threadName, registrationWrapper));
|
.handler(new RegistrationLocalHandlerClient<C>(threadName, registrationWrapper));
|
||||||
|
|
||||||
manageForShutdown(localBoss);
|
manageForShutdown(localBoss);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (options.host == null) {
|
if (config.host == null) {
|
||||||
throw new IllegalArgumentException("You must define what host you want to connect to.");
|
throw new IllegalArgumentException("You must define what host you want to connect to.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.tcpPort < 0 && options.udpPort < 0) {
|
if (config.tcpPort <= 0 && config.udpPort <= 0) {
|
||||||
throw new IllegalArgumentException("You must define what port you want to connect to.");
|
throw new IllegalArgumentException("You must define what port you want to connect to.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.tcpPort > 0) {
|
if (config.tcpPort > 0) {
|
||||||
Bootstrap tcpBootstrap = new Bootstrap();
|
Bootstrap tcpBootstrap = new Bootstrap();
|
||||||
this.bootstraps.add(new BootstrapWrapper("TCP", options.host, options.tcpPort, tcpBootstrap));
|
this.bootstraps.add(new BootstrapWrapper("TCP", config.host, config.tcpPort, tcpBootstrap));
|
||||||
|
|
||||||
if (isAndroid) {
|
if (isAndroid) {
|
||||||
// android ONLY supports OIO (not NIO)
|
// android ONLY supports OIO (not NIO)
|
||||||
@ -173,7 +173,7 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||||||
tcpBootstrap.group(boss)
|
tcpBootstrap.group(boss)
|
||||||
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
||||||
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
||||||
.remoteAddress(options.host, options.tcpPort)
|
.remoteAddress(config.host, config.tcpPort)
|
||||||
.handler(new RegistrationRemoteHandlerClientTCP<C>(threadName,
|
.handler(new RegistrationRemoteHandlerClientTCP<C>(threadName,
|
||||||
registrationWrapper,
|
registrationWrapper,
|
||||||
serializationManager));
|
serializationManager));
|
||||||
@ -184,9 +184,9 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (options.udpPort > 0) {
|
if (config.udpPort > 0) {
|
||||||
Bootstrap udpBootstrap = new Bootstrap();
|
Bootstrap udpBootstrap = new Bootstrap();
|
||||||
this.bootstraps.add(new BootstrapWrapper("UDP", options.host, options.udpPort, udpBootstrap));
|
this.bootstraps.add(new BootstrapWrapper("UDP", config.host, config.udpPort, udpBootstrap));
|
||||||
|
|
||||||
if (isAndroid) {
|
if (isAndroid) {
|
||||||
// android ONLY supports OIO (not NIO)
|
// android ONLY supports OIO (not NIO)
|
||||||
@ -204,7 +204,7 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||||||
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
||||||
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
||||||
.localAddress(new InetSocketAddress(0)) // bind to wildcard
|
.localAddress(new InetSocketAddress(0)) // bind to wildcard
|
||||||
.remoteAddress(new InetSocketAddress(options.host, options.udpPort))
|
.remoteAddress(new InetSocketAddress(config.host, config.udpPort))
|
||||||
.handler(new RegistrationRemoteHandlerClientUDP<C>(threadName,
|
.handler(new RegistrationRemoteHandlerClientUDP<C>(threadName,
|
||||||
registrationWrapper,
|
registrationWrapper,
|
||||||
serializationManager));
|
serializationManager));
|
||||||
|
@ -30,15 +30,19 @@ class Configuration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the TCP port to use. The server will listen on this port, the client will connect to it.
|
* Specify the TCP port to use. The server will listen on this port, the client will connect to it.
|
||||||
|
* <p>
|
||||||
|
* Must be > 0 to be used
|
||||||
*/
|
*/
|
||||||
public int tcpPort = -1;
|
public int tcpPort = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the UDP port to use. The server will listen on this port, the client will connect to it.
|
* Specify the UDP port to use. The server will listen on this port, the client will connect to it.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Must be > 0 to be used
|
||||||
|
* <p>
|
||||||
* UDP requires TCP to handshake
|
* UDP requires TCP to handshake
|
||||||
*/
|
*/
|
||||||
public int udpPort = -1;
|
public int udpPort = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the local channel name to use, if the default is not wanted.
|
* Specify the local channel name to use, if the default is not wanted.
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
package dorkbox.network;
|
package dorkbox.network;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.net.Socket;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@ -59,6 +59,8 @@ import io.netty.channel.socket.oio.OioServerSocketChannel;
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class Server<C extends Connection> extends EndPointServer<C> {
|
class Server<C extends Connection> extends EndPointServer<C> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the version number.
|
* Gets the version number.
|
||||||
*/
|
*/
|
||||||
@ -84,7 +86,8 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||||||
private final String localChannelName;
|
private final String localChannelName;
|
||||||
private final String hostName;
|
private final String hostName;
|
||||||
|
|
||||||
private final CountDownLatch blockUntilDone = new CountDownLatch(1);
|
private volatile boolean isRunning = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a LOCAL <b>only</b> server, with the default serialization scheme.
|
* Starts a LOCAL <b>only</b> server, with the default serialization scheme.
|
||||||
@ -99,21 +102,21 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("AutoBoxing")
|
@SuppressWarnings("AutoBoxing")
|
||||||
public
|
public
|
||||||
Server(Configuration options) throws InitializationException, SecurityException, IOException {
|
Server(Configuration config) throws InitializationException, SecurityException, IOException {
|
||||||
// watch-out for serialization... it can be NULL incoming. The EndPoint (superclass) sets it, if null, so
|
// watch-out for serialization... it can be NULL incoming. The EndPoint (superclass) sets it, if null, so
|
||||||
// you have to make sure to use this.serialization
|
// you have to make sure to use this.serialization
|
||||||
super(options);
|
super(config);
|
||||||
|
|
||||||
tcpPort = options.tcpPort;
|
tcpPort = config.tcpPort;
|
||||||
udpPort = options.udpPort;
|
udpPort = config.udpPort;
|
||||||
|
|
||||||
localChannelName = options.localChannelName;
|
localChannelName = config.localChannelName;
|
||||||
|
|
||||||
if (options.host == null) {
|
if (config.host == null) {
|
||||||
hostName = "0.0.0.0";
|
hostName = "0.0.0.0";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hostName = options.host;
|
hostName = config.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -213,7 +216,7 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||||||
serializationManager));
|
serializationManager));
|
||||||
|
|
||||||
// have to check options.host for null. we don't bind to 0.0.0.0, we bind to "null" to get the "any" address!
|
// have to check options.host for null. we don't bind to 0.0.0.0, we bind to "null" to get the "any" address!
|
||||||
if (options.host != null) {
|
if (config.host != null) {
|
||||||
tcpBootstrap.localAddress(hostName, tcpPort);
|
tcpBootstrap.localAddress(hostName, tcpPort);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -351,8 +354,9 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||||||
future = udpBootstrap.bind();
|
future = udpBootstrap.bind();
|
||||||
future.await();
|
future.await();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String errorMessage = stopWithErrorMessage(logger2, "Could not bind to address " + hostName + " UDP port " +
|
String errorMessage = stopWithErrorMessage(logger2,
|
||||||
udpPort + " on the server.",
|
"Could not bind to address " + hostName + " UDP port " + udpPort +
|
||||||
|
" on the server.",
|
||||||
e);
|
e);
|
||||||
throw new IllegalArgumentException(errorMessage);
|
throw new IllegalArgumentException(errorMessage);
|
||||||
}
|
}
|
||||||
@ -369,11 +373,69 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||||||
manageForShutdown(future);
|
manageForShutdown(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRunning = true;
|
||||||
|
|
||||||
// we now BLOCK until the stop method is called.
|
// we now BLOCK until the stop method is called.
|
||||||
// if we want to continue running code in the server, bind should be called in a separate, non-daemon thread.
|
// if we want to continue running code in the server, bind should be called in a separate, non-daemon thread.
|
||||||
if (blockUntilTerminate) {
|
if (blockUntilTerminate) {
|
||||||
waitForShutdown();
|
waitForShutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected
|
||||||
|
void stopExtraActions() {
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this server has successfully bound to an IP address and is running
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
boolean isRunning() {
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if different server (using the specified configuration) is already running. This will check across JVMs by checking the
|
||||||
|
* network socket directly, and assumes that if the port is in use and answers, then the server is "running". This does not try to
|
||||||
|
* authenticate or validate the connection.
|
||||||
|
* <p>
|
||||||
|
* This does not check local-channels (which are intra-JVM only) or UDP connections.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return true if the configuration matches and can connect (but not verify) to the TCP control socket.
|
||||||
|
*/
|
||||||
|
public static
|
||||||
|
boolean isRunning(Configuration config) {
|
||||||
|
String host = config.host;
|
||||||
|
|
||||||
|
// for us, we want a "null" host to connect to the "any" interface.
|
||||||
|
if (host == null) {
|
||||||
|
host = "0.0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.tcpPort == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket sock = null;
|
||||||
|
|
||||||
|
// since we check the socket, if we cannot connect to a socket, then we're done.
|
||||||
|
try {
|
||||||
|
sock = new Socket(host, config.tcpPort);
|
||||||
|
// if we can connect to the socket, it means that we are already running.
|
||||||
|
return sock.isConnected();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
if (sock != null) {
|
||||||
|
try {
|
||||||
|
sock.close();
|
||||||
|
} catch (IOException ignored2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,32 +115,32 @@ class EndPointBase<C extends Connection> extends EndPoint {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param type this is either "Client" or "Server", depending on who is creating this endpoint.
|
* @param type this is either "Client" or "Server", depending on who is creating this endpoint.
|
||||||
* @param options these are the specific connection options
|
* @param config these are the specific connection options
|
||||||
*
|
*
|
||||||
* @throws InitializationException
|
* @throws InitializationException
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public
|
public
|
||||||
EndPointBase(Class<? extends EndPointBase> type, final Configuration options) throws InitializationException, SecurityException, IOException {
|
EndPointBase(Class<? extends EndPointBase> type, final Configuration config) throws InitializationException, SecurityException, IOException {
|
||||||
super(type);
|
super(type);
|
||||||
|
|
||||||
// make sure that 'localhost' is ALWAYS our specific loopback IP address
|
// make sure that 'localhost' is ALWAYS our specific loopback IP address
|
||||||
if (options.host != null && (options.host.equals("localhost") || options.host.startsWith("127."))) {
|
if (config.host != null && (config.host.equals("localhost") || config.host.startsWith("127."))) {
|
||||||
// localhost IP might not always be 127.0.0.1
|
// localhost IP might not always be 127.0.0.1
|
||||||
options.host = NetUtil.LOCALHOST.getHostAddress();
|
config.host = NetUtil.LOCALHOST.getHostAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialization stuff
|
// serialization stuff
|
||||||
if (options.serialization != null) {
|
if (config.serialization != null) {
|
||||||
this.serializationManager = options.serialization;
|
this.serializationManager = config.serialization;
|
||||||
} else {
|
} else {
|
||||||
this.serializationManager = CryptoSerializationManager.DEFAULT();
|
this.serializationManager = CryptoSerializationManager.DEFAULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup our RMI serialization managers. Can only be called once
|
// setup our RMI serialization managers. Can only be called once
|
||||||
rmiEnabled = serializationManager.initRmiSerialization();
|
rmiEnabled = serializationManager.initRmiSerialization();
|
||||||
rmiExecutor = options.rmiExecutor;
|
rmiExecutor = config.rmiExecutor;
|
||||||
|
|
||||||
|
|
||||||
// The registration wrapper permits the registration process to access protected/package fields/methods, that we don't want
|
// The registration wrapper permits the registration process to access protected/package fields/methods, that we don't want
|
||||||
@ -153,17 +153,17 @@ class EndPointBase<C extends Connection> extends EndPoint {
|
|||||||
|
|
||||||
|
|
||||||
// we have to be able to specify WHAT property store we want to use, since it can change!
|
// we have to be able to specify WHAT property store we want to use, since it can change!
|
||||||
if (options.settingsStore == null) {
|
if (config.settingsStore == null) {
|
||||||
this.propertyStore = new PropertyStore();
|
this.propertyStore = new PropertyStore();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.propertyStore = options.settingsStore;
|
this.propertyStore = config.settingsStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.propertyStore.init(this.serializationManager, null);
|
this.propertyStore.init(this.serializationManager, null);
|
||||||
|
|
||||||
// null it out, since it is sensitive!
|
// null it out, since it is sensitive!
|
||||||
options.settingsStore = null;
|
config.settingsStore = null;
|
||||||
|
|
||||||
|
|
||||||
if (!(this.propertyStore instanceof NullSettingsStore)) {
|
if (!(this.propertyStore instanceof NullSettingsStore)) {
|
||||||
@ -217,7 +217,7 @@ class EndPointBase<C extends Connection> extends EndPoint {
|
|||||||
if (this.rmiEnabled) {
|
if (this.rmiEnabled) {
|
||||||
// these register the listener for registering a class implementation for RMI (internal use only)
|
// these register the listener for registering a class implementation for RMI (internal use only)
|
||||||
this.connectionManager.add(new RegisterRmiSystemListener());
|
this.connectionManager.add(new RegisterRmiSystemListener());
|
||||||
this.globalRmiBridge = new RmiBridge(logger, options.rmiExecutor, true);
|
this.globalRmiBridge = new RmiBridge(logger, config.rmiExecutor, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.globalRmiBridge = null;
|
this.globalRmiBridge = null;
|
||||||
|
@ -50,8 +50,8 @@ class EndPointClient<C extends Connection> extends EndPointBase<C> implements Ru
|
|||||||
|
|
||||||
|
|
||||||
public
|
public
|
||||||
EndPointClient(Configuration options) throws InitializationException, SecurityException, IOException {
|
EndPointClient(Configuration config) throws InitializationException, SecurityException, IOException {
|
||||||
super(Client.class, options);
|
super(Client.class, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -30,8 +30,8 @@ public
|
|||||||
class EndPointServer<C extends Connection> extends EndPointBase<C> {
|
class EndPointServer<C extends Connection> extends EndPointBase<C> {
|
||||||
|
|
||||||
public
|
public
|
||||||
EndPointServer(final Configuration options) throws InitializationException, SecurityException, IOException {
|
EndPointServer(final Configuration config) throws InitializationException, SecurityException, IOException {
|
||||||
super(Server.class, options);
|
super(Server.class, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user