diff --git a/engine/src/networking/com/jme3/network/Client.java b/engine/src/networking/com/jme3/network/Client.java
index 8b4fc2b07..b324954fc 100644
--- a/engine/src/networking/com/jme3/network/Client.java
+++ b/engine/src/networking/com/jme3/network/Client.java
@@ -79,6 +79,12 @@ public interface Client extends MessageConnection
*/
public void send( Message message );
+ /**
+ * Sends a message to the other end of the connection using
+ * the specified alternate channel.
+ */
+ public void send( int channel, Message message );
+
/**
* Closes this connection to the server.
*/
diff --git a/engine/src/networking/com/jme3/network/MessageConnection.java b/engine/src/networking/com/jme3/network/MessageConnection.java
index 712d82108..1f5730e84 100644
--- a/engine/src/networking/com/jme3/network/MessageConnection.java
+++ b/engine/src/networking/com/jme3/network/MessageConnection.java
@@ -46,5 +46,11 @@ public interface MessageConnection
* Sends a message to the other end of the connection.
*/
public void send( Message message );
+
+ /**
+ * Sends a message to the other end of the connection using
+ * the specified alternate channel.
+ */
+ public void send( int channel, Message message );
}
diff --git a/engine/src/networking/com/jme3/network/Network.java b/engine/src/networking/com/jme3/network/Network.java
index c32d38124..81fccee42 100644
--- a/engine/src/networking/com/jme3/network/Network.java
+++ b/engine/src/networking/com/jme3/network/Network.java
@@ -34,6 +34,7 @@ package com.jme3.network;
import com.jme3.network.base.DefaultClient;
import com.jme3.network.base.DefaultServer;
+import com.jme3.network.base.TcpConnectorFactory;
import com.jme3.network.kernel.tcp.SelectorKernel;
import com.jme3.network.kernel.tcp.SocketConnector;
import com.jme3.network.kernel.udp.UdpConnector;
@@ -85,7 +86,7 @@ public class Network
* @param tcpPort The port upon which the TCP hosting will listen for new connections.
* @param udpPort The port upon which the UDP hosting will listen for new 'fast' UDP
* messages. Set to -1 if 'fast' traffic should go over TCP. This will
- * comletely disable UDP traffic for this server.
+ * completely disable UDP traffic for this server.
*/
public static Server createServer( String gameName, int version, int tcpPort, int udpPort ) throws IOException
{
@@ -164,7 +165,7 @@ public class Network
UdpConnector fast = remoteUdpPort == -1 ? null : new UdpConnector( remoteAddress, remoteUdpPort );
SocketConnector reliable = new SocketConnector( remoteAddress, hostPort );
- return new DefaultClient( gameName, version, reliable, fast );
+ return new DefaultClient( gameName, version, reliable, fast, new TcpConnectorFactory(remoteAddress) );
}
@@ -185,7 +186,7 @@ public class Network
UdpConnector fast = new UdpConnector( address, remoteUdpPort );
SocketConnector reliable = new SocketConnector( address, port );
- setConnectors( reliable, fast );
+ setPrimaryConnectors( reliable, fast, new TcpConnectorFactory(address) );
}
}
}
diff --git a/engine/src/networking/com/jme3/network/Server.java b/engine/src/networking/com/jme3/network/Server.java
index 8a1b2cfb2..4099340a5 100644
--- a/engine/src/networking/com/jme3/network/Server.java
+++ b/engine/src/networking/com/jme3/network/Server.java
@@ -76,12 +76,39 @@ public interface Server
*/
public void broadcast( Filter super HostedConnection> filter, Message message );
+ /**
+ * Sends the specified message over the specified alternate channel to all connected
+ * clients that match the filter. If no filter is specified then this is the same as
+ * calling broadcast(message) and the message will be delivered to
+ * all connections.
+ *
Examples:
+ *
+ * // Broadcast to connections: conn1, conn2, and conn3
+ * server.broadcast( Filters.in( conn1, conn2, conn3 ), message );
+ *
+ * // Broadcast to all connections exception source
+ * server.broadcast( Filters.notEqualTo( source ), message );
+ *
+ */
+ public void broadcast( int channel, Filter super HostedConnection> filter, Message message );
+
/**
* Start the server so that it will began accepting new connections
* and processing messages.
*/
public void start();
+ /**
+ * Adds an alternate channel to the server, using the specified port. This is an
+ * entirely separate connection where messages are sent and received in parallel
+ * to the two primary default channels. All channels must be added before the connection
+ * is started.
+ * Returns the ID of the created channel for use when specifying the channel in send or
+ * broadcast calls. The ID is returned entirely out of convenience since the IDs
+ * are predictably incremented. The first channel is 0, second is 1, and so on.
+ */
+ public int addChannel( int port );
+
/**
* Returns true if the server has been started.
*/
diff --git a/engine/src/networking/com/jme3/network/base/ConnectorFactory.java b/engine/src/networking/com/jme3/network/base/ConnectorFactory.java
new file mode 100644
index 000000000..375e91e21
--- /dev/null
+++ b/engine/src/networking/com/jme3/network/base/ConnectorFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.network.base;
+
+import com.jme3.network.kernel.Connector;
+import java.io.IOException;
+
+
+/**
+ * Creates Connectors for a specific host.
+ *
+ * @version $Revision$
+ * @author Paul Speed
+ */
+public interface ConnectorFactory
+{
+ public Connector createConnector( int channel, int port ) throws IOException;
+}
diff --git a/engine/src/networking/com/jme3/network/base/DefaultClient.java b/engine/src/networking/com/jme3/network/base/DefaultClient.java
index 3b3e5f022..e84692f3a 100644
--- a/engine/src/networking/com/jme3/network/base/DefaultClient.java
+++ b/engine/src/networking/com/jme3/network/base/DefaultClient.java
@@ -35,8 +35,10 @@ package com.jme3.network.base;
import com.jme3.network.ClientStateListener.DisconnectInfo;
import com.jme3.network.*;
import com.jme3.network.kernel.Connector;
+import com.jme3.network.message.ChannelInfoMessage;
import com.jme3.network.message.ClientRegistrationMessage;
import com.jme3.network.message.DisconnectMessage;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -62,6 +64,7 @@ public class DefaultClient implements Client
// separate.
private static final int CH_RELIABLE = 0;
private static final int CH_UNRELIABLE = 1;
+ private static final int CH_FIRST = 2;
private ThreadLocal dataBuffer = new ThreadLocal();
@@ -75,6 +78,8 @@ public class DefaultClient implements Client
private List> errorListeners = new CopyOnWriteArrayList>();
private Redispatch dispatcher = new Redispatch();
private List channels = new ArrayList();
+
+ private ConnectorFactory connectorFactory;
public DefaultClient( String gameName, int version )
{
@@ -82,13 +87,14 @@ public class DefaultClient implements Client
this.version = version;
}
- public DefaultClient( String gameName, int version, Connector reliable, Connector fast )
+ public DefaultClient( String gameName, int version, Connector reliable, Connector fast,
+ ConnectorFactory connectorFactory )
{
this( gameName, version );
- setPrimaryConnectors( reliable, fast );
+ setPrimaryConnectors( reliable, fast, connectorFactory );
}
- protected void setPrimaryConnectors( Connector reliable, Connector fast )
+ protected void setPrimaryConnectors( Connector reliable, Connector fast, ConnectorFactory connectorFactory )
{
if( reliable == null )
throw new IllegalArgumentException( "The reliable connector cannot be null." );
@@ -97,6 +103,7 @@ public class DefaultClient implements Client
if( !channels.isEmpty() )
throw new IllegalStateException( "Channels already exist." );
+ this.connectorFactory = connectorFactory;
channels.add(new ConnectorAdapter(reliable, dispatcher, dispatcher, true));
if( fast != null ) {
channels.add(new ConnectorAdapter(fast, dispatcher, dispatcher, false));
@@ -203,6 +210,13 @@ public class DefaultClient implements Client
send(CH_UNRELIABLE, message, true);
}
}
+
+ public void send( int channel, Message message )
+ {
+ if( channel < 0 || channel + CH_FIRST >= channels.size() )
+ throw new IllegalArgumentException( "Channel is undefined:" + channel );
+ send( channel + CH_FIRST, message, true );
+ }
protected void send( int channel, Message message, boolean waitForConnected )
{
@@ -340,6 +354,29 @@ public class DefaultClient implements Client
}
}
+ protected void configureChannels( long tempId, int[] ports ) {
+
+ try {
+ for( int i = 0; i < ports.length; i++ ) {
+ Connector c = connectorFactory.createConnector( i, ports[i] );
+ ConnectorAdapter ca = new ConnectorAdapter(c, dispatcher, dispatcher, true);
+ int ch = channels.size();
+ channels.add( ca );
+
+ // Need to send the connection its hook-up registration
+ // and start it.
+ ca.start();
+ ClientRegistrationMessage reg;
+ reg = new ClientRegistrationMessage();
+ reg.setId(tempId);
+ reg.setReliable(true);
+ send( ch, reg, false );
+ }
+ } catch( IOException e ) {
+ throw new RuntimeException( "Error configuring channels", e );
+ }
+ }
+
protected void dispatch( Message m )
{
// Pull off the connection management messages we're
@@ -351,7 +388,12 @@ public class DefaultClient implements Client
connecting.countDown();
fireConnected();
return;
- } if( m instanceof DisconnectMessage ) {
+ } else if( m instanceof ChannelInfoMessage ) {
+ // This is an interum step in the connection process and
+ // now we need to add a bunch of connections
+ configureChannels( ((ChannelInfoMessage)m).getId(), ((ChannelInfoMessage)m).getPorts() );
+ return;
+ } else if( m instanceof DisconnectMessage ) {
// Can't do too much else yet
String reason = ((DisconnectMessage)m).getReason();
log.log( Level.SEVERE, "Connection terminated, reason:{0}.", reason );
diff --git a/engine/src/networking/com/jme3/network/base/DefaultServer.java b/engine/src/networking/com/jme3/network/base/DefaultServer.java
index 628e8ab54..8b8ed34c6 100644
--- a/engine/src/networking/com/jme3/network/base/DefaultServer.java
+++ b/engine/src/networking/com/jme3/network/base/DefaultServer.java
@@ -35,8 +35,10 @@ package com.jme3.network.base;
import com.jme3.network.*;
import com.jme3.network.kernel.Endpoint;
import com.jme3.network.kernel.Kernel;
+import com.jme3.network.message.ChannelInfoMessage;
import com.jme3.network.message.ClientRegistrationMessage;
import com.jme3.network.message.DisconnectMessage;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -60,15 +62,17 @@ public class DefaultServer implements Server
// unreliable
private static final int CH_RELIABLE = 0;
private static final int CH_UNRELIABLE = 1;
+ private static final int CH_FIRST = 2;
private boolean isRunning = false;
private AtomicInteger nextId = new AtomicInteger(0);
private String gameName;
private int version;
- //private KernelFactory kernelFactory = KernelFactory.DEFAULT;
+ private KernelFactory kernelFactory = KernelFactory.DEFAULT;
private KernelAdapter reliableAdapter;
private KernelAdapter fastAdapter;
private List channels = new ArrayList();
+ private List alternatePorts = new ArrayList();
private Redispatch dispatcher = new Redispatch();
private Map connections = new ConcurrentHashMap();
private Map endpointConnections
@@ -109,6 +113,42 @@ public class DefaultServer implements Server
return version;
}
+ public int addChannel( int port )
+ {
+ if( isRunning )
+ throw new IllegalStateException( "Channels cannot be added once server is started." );
+
+ // Note: it does bug me that channels aren't 100% universal and
+ // setup externally but it requires a more invasive set of changes
+ // for "connection types" and some kind of registry of kernel and
+ // connector factories. This really would be the best approach and
+ // would allow all kinds of channel customization maybe... but for
+ // now, we hard-code the standard connections and treat the +2 extras
+ // differently.
+
+ // Check for consistency with the channels list
+ if( channels.size() - CH_FIRST != alternatePorts.size() )
+ throw new IllegalStateException( "Channel and port lists do not match." );
+
+ try {
+ int result = alternatePorts.size();
+ alternatePorts.add(port);
+
+ Kernel kernel = kernelFactory.createKernel(result, port);
+ channels.add( new KernelAdapter(this, kernel, dispatcher, true) );
+
+ return result;
+ } catch( IOException e ) {
+ throw new RuntimeException( "Error adding channel for port:" + port, e );
+ }
+ }
+
+ protected void checkChannel( int channel )
+ {
+ if( channel < 0 || channel >= alternatePorts.size() )
+ throw new IllegalArgumentException( "Channel is undefined:" + channel );
+ }
+
public void start()
{
if( isRunning )
@@ -163,7 +203,6 @@ public class DefaultServer implements Server
FilterAdapter adapter = filter == null ? null : new FilterAdapter(filter);
- // Ignore the filter for the moment
if( message.isReliable() || fastAdapter == null ) {
// Don't need to copy the data because message protocol is already
// giving us a fresh buffer
@@ -173,6 +212,20 @@ public class DefaultServer implements Server
}
}
+ public void broadcast( int channel, Filter super HostedConnection> filter, Message message )
+ {
+ if( connections.isEmpty() )
+ return;
+
+ checkChannel(channel);
+
+ ByteBuffer buffer = MessageProtocol.messageToBuffer(message, null);
+
+ FilterAdapter adapter = filter == null ? null : new FilterAdapter(filter);
+
+ channels.get(channel+CH_FIRST).broadcast( adapter, buffer, true, false );
+ }
+
public HostedConnection getConnection( int id )
{
return connections.get(id);
@@ -295,7 +348,10 @@ public class DefaultServer implements Server
}
// Else send the extra channel information to the client
- // TBD
+ if( !alternatePorts.isEmpty() ) {
+ ChannelInfoMessage cim = new ChannelInfoMessage( m.getId(), alternatePorts );
+ c.send(cim);
+ }
}
if( c.isComplete() ) {
@@ -349,7 +405,7 @@ public class DefaultServer implements Server
// closed already.
// Also note: this method will be called multiple times per
- // HostedConnection if it has two endpoints.
+ // HostedConnection if it has multiple endpoints.
Connection removed = null;
synchronized( this ) {
@@ -431,6 +487,13 @@ public class DefaultServer implements Server
channels[CH_UNRELIABLE].send( buffer );
}
}
+
+ public void send( int channel, Message message )
+ {
+ checkChannel(channel);
+ ByteBuffer buffer = MessageProtocol.messageToBuffer(message, null);
+ channels[channel+CH_FIRST].send(buffer);
+ }
protected void closeConnection()
{
diff --git a/engine/src/networking/com/jme3/network/base/KernelFactory.java b/engine/src/networking/com/jme3/network/base/KernelFactory.java
new file mode 100644
index 000000000..ca1ce4852
--- /dev/null
+++ b/engine/src/networking/com/jme3/network/base/KernelFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.network.base;
+
+import com.jme3.network.kernel.Kernel;
+import java.io.IOException;
+
+
+/**
+ * Supplied to the DefaultServer to create any additional
+ * channel kernels that might be required.
+ *
+ * @version $Revision$
+ * @author Paul Speed
+ */
+public interface KernelFactory
+{
+ public static final KernelFactory DEFAULT = new NioKernelFactory();
+
+ public Kernel createKernel( int channel, int port ) throws IOException;
+}
diff --git a/engine/src/networking/com/jme3/network/base/NioKernelFactory.java b/engine/src/networking/com/jme3/network/base/NioKernelFactory.java
new file mode 100644
index 000000000..79b08def4
--- /dev/null
+++ b/engine/src/networking/com/jme3/network/base/NioKernelFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.network.base;
+
+import com.jme3.network.kernel.Kernel;
+import com.jme3.network.kernel.tcp.SelectorKernel;
+import java.io.IOException;
+
+
+/**
+ * KernelFactory implemention for creating TCP kernels
+ * using the NIO selector model.
+ *
+ * @version $Revision$
+ * @author Paul Speed
+ */
+public class NioKernelFactory implements KernelFactory
+{
+ public Kernel createKernel( int channel, int port ) throws IOException
+ {
+ return new SelectorKernel(port);
+ }
+}
diff --git a/engine/src/networking/com/jme3/network/base/TcpConnectorFactory.java b/engine/src/networking/com/jme3/network/base/TcpConnectorFactory.java
new file mode 100644
index 000000000..c0de8d397
--- /dev/null
+++ b/engine/src/networking/com/jme3/network/base/TcpConnectorFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.network.base;
+
+import com.jme3.network.kernel.Connector;
+import com.jme3.network.kernel.tcp.SocketConnector;
+import java.io.IOException;
+import java.net.InetAddress;
+
+
+/**
+ * Creates TCP connectors to a specific remote address.
+ *
+ * @version $Revision$
+ * @author Paul Speed
+ */
+public class TcpConnectorFactory implements ConnectorFactory
+{
+ private InetAddress remoteAddress;
+
+ public TcpConnectorFactory( InetAddress remoteAddress )
+ {
+ this.remoteAddress = remoteAddress;
+ }
+
+ public Connector createConnector( int channel, int port ) throws IOException
+ {
+ return new SocketConnector( remoteAddress, port );
+ }
+}
diff --git a/engine/src/networking/com/jme3/network/message/ChannelInfoMessage.java b/engine/src/networking/com/jme3/network/message/ChannelInfoMessage.java
new file mode 100644
index 000000000..91e54bc6b
--- /dev/null
+++ b/engine/src/networking/com/jme3/network/message/ChannelInfoMessage.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.network.message;
+
+import com.jme3.network.AbstractMessage;
+import com.jme3.network.serializing.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Contains information about any extra server channels (if they exist).
+ *
+ * @author Paul Speed
+ */
+@Serializable()
+public class ChannelInfoMessage extends AbstractMessage {
+ private long id;
+ private int[] ports;
+
+ public ChannelInfoMessage() {
+ super( true );
+ }
+
+ public ChannelInfoMessage( long id, List ports ) {
+ super( true );
+ this.id = id;
+ this.ports = new int[ports.size()];
+ for( int i = 0; i < ports.size(); i++ ) {
+ this.ports[i] = ports.get(i);
+ }
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public int[] getPorts() {
+ return ports;
+ }
+
+ public String toString() {
+ return "ChannelInfoMessage[" + id + ", " + Arrays.asList(ports) + "]";
+ }
+}
diff --git a/engine/src/networking/com/jme3/network/serializing/Serializer.java b/engine/src/networking/com/jme3/network/serializing/Serializer.java
index 11773b737..a4e197123 100644
--- a/engine/src/networking/com/jme3/network/serializing/Serializer.java
+++ b/engine/src/networking/com/jme3/network/serializing/Serializer.java
@@ -33,6 +33,7 @@
package com.jme3.network.serializing;
import com.jme3.math.Vector3f;
+import com.jme3.network.message.ChannelInfoMessage;
import com.jme3.network.message.ClientRegistrationMessage;
import com.jme3.network.message.DisconnectMessage;
import com.jme3.network.message.GZIPCompressedMessage;
@@ -126,6 +127,7 @@ public abstract class Serializer {
registerClass(DisconnectMessage.class);
registerClass(ClientRegistrationMessage.class);
+ registerClass(ChannelInfoMessage.class);
}
/**