2
0
Эх сурвалжийг харах

Added a bunch of javadoc and changed the names of one of the
method sets to be a little less confusing.

Paul Speed 9 жил өмнө
parent
commit
3a4624a5fe

+ 3 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/Asynchronous.java

@@ -41,7 +41,9 @@ import static java.lang.annotation.RetentionPolicy.*;
 /**
  *  Indicates that a given method should be executed asynchronously
  *  through the RMI service.  This must annotate the method on the
- *  shared interface for it to have an effect.
+ *  shared interface for it to have an effect.  If reliable=false
+ *  is specified then remote method invocation is done over UDP
+ *  instead of TCP, ie: unreliably... but faster.
  *
  *  @author    Paul Speed
  */

+ 19 - 2
jme3-networking/src/main/java/com/jme3/network/service/rmi/CallType.java

@@ -34,10 +34,27 @@ package com.jme3.network.service.rmi;
 
 
 /**
- *
+ *  Internal type denoting the type of call to make when remotely
+ *  invoking methods.
  *
  *  @author    Paul Speed
  */
 public enum CallType {
-    Synchronous, Asynchronous, Unreliable
+    /**
+     *  Caller will block until a response is received and returned.
+     */
+    Synchronous,
+    
+    /**
+     *  Caller does not block or wait for a response.  The other end
+     *  of the connection will also not send one.
+     */ 
+    Asynchronous,
+    
+    /**
+     *  Similar to asynchronous in that no response is expected or sent
+     *  but differs in that the call will be sent over UDP and so may
+     *  not make it to the other end.
+     */ 
+    Unreliable
 }

+ 2 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/ClassInfo.java

@@ -39,7 +39,8 @@ import java.util.List;
 
 
 /**
- *
+ *  Internal information about a shared class.  This is the information
+ *  that is sent over the wire for shared types.
  *
  *  @author    Paul Speed
  */

+ 2 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/ClassInfoRegistry.java

@@ -40,7 +40,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 
 /**
- *
+ *  Internal registry of shared types and their ClassInfo and MethodInfo
+ *  objects.
  *
  *  @author    Paul Speed
  */

+ 2 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/MethodInfo.java

@@ -39,7 +39,8 @@ import javax.jws.Oneway;
 
 
 /**
- *
+ *  Internal information about shared methods.  This is part of the data that
+ *  is passed over the wire when an object is shared. 
  *
  *  @author    Paul Speed
  */

+ 1 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/RemoteObjectHandler.java

@@ -39,7 +39,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 
 /**
- *
+ *  Used internally to remotely invoke methods on RMI shared objects.
  *
  *  @author    Paul Speed
  */

+ 48 - 0
jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiClientService.java

@@ -41,7 +41,23 @@ import java.util.List;
 
 
 /**
+ *  A service that can be added to the client to support a simple
+ *  shared objects protocol.
  *
+ *  <p>Objects are shared by adding them to the RmiRegistry with one of the
+ *  share() methods.  Shared objects must have a separate interface and implementation.
+ *  The interface is what the other end of the connection will use to interact
+ *  with the object and that interface class must be available on both ends of
+ *  the connection.  The implementing class need only be on the sharing end.</p>
+ *
+ *  <p>Shared objects can be accessed on the other end of the connection by
+ *  using one of the RmiRegistry's getRemoteObject() methods.  These can be
+ *  used to lookup an object by class if it is a shared singleton or by name
+ *  if it was registered with a name.</p>
+ * 
+ *  <p>Note: This RMI implementation is not as advanced as Java's regular
+ *  RMI as it won't marshall shared references, ie: you can't pass
+ *  a shared objects as an argument to another shared object's method.</p>
  *
  *  @author    Paul Speed
  */
@@ -64,18 +80,42 @@ public class RmiClientService extends AbstractClientService {
         this.rmiObjectId = rmiObjectId;
     }
 
+    /**
+     *  Shares the specified object with the server and associates it with the 
+     *  specified type.  Objects shared in this way are available in the connection-specific
+     *  RMI registry on the server and are not available to other connections.
+     */
     public <T> void share( T object, Class<? super T> type ) {
         share(defaultChannel, object, type);       
     }
     
+    /**
+     *  Shares the specified object with the server and associates it with the 
+     *  specified type.  Objects shared in this way are available in the connection-specific
+     *  RMI registry on the server and are not available to other connections.
+     *  All object related communication will be done over the specified connection
+     *  channel.
+     */
     public <T> void share( byte channel, T object, Class<? super T> type ) {
         share(channel, type.getName(), object, type);
     } 
     
+    /**
+     *  Shares the specified object with the server and associates it with the 
+     *  specified name.  Objects shared in this way are available in the connection-specific
+     *  RMI registry on the server and are not available to other connections.
+     */
     public <T> void share( String name, T object, Class<? super T> type ) {
         share(defaultChannel, name, object, type);
     }
     
+    /**
+     *  Shares the specified object with the server and associates it with the 
+     *  specified name.  Objects shared in this way are available in the connection-specific
+     *  RMI registry on the server and are not available to other connections.
+     *  All object related communication will be done over the specified connection
+     *  channel.
+     */
     public <T> void share( byte channel, String name, T object, Class<? super T> type ) {
         if( !isStarted ) {
             synchronized(pending) {
@@ -90,10 +130,18 @@ public class RmiClientService extends AbstractClientService {
         rmi.share(channel, name, object, type);
     }
 
+    /**
+     *  Looks up a remote object on the server by type and returns a local proxy to the 
+     *  remote object that was shared on the other end of the network connection.  
+     */
     public <T> T getRemoteObject( Class<T> type ) {
         return rmi.getRemoteObject(type);
     }
         
+    /**
+     *  Looks up a remote object on the server by name and returns a local proxy to the 
+     *  remote object that was shared on the other end of the network connection.  
+     */
     public <T> T getRemoteObject( String name, Class<T> type ) {
         return rmi.getRemoteObject(name, type);
     }    

+ 5 - 1
jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiContext.java

@@ -45,7 +45,11 @@ import com.jme3.network.HostedConnection;
  */
 public class RmiContext {
     private static final ThreadLocal<HostedConnection> connection = new ThreadLocal<HostedConnection>();
-    
+ 
+    /**
+     *  Returns the HostedConnection that is responsible for any
+     *  RMI-related calls on this thread.
+     */   
     public static HostedConnection getRmiConnection() {
         return connection.get();
     }

+ 59 - 0
jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiHostedService.java

@@ -46,7 +46,30 @@ import java.util.logging.Logger;
 
 
 /**
+ *  A service that can be added to the host to support a simple
+ *  shared objects protocol.
  *
+ *  <p>Objects are shared by adding them to the RmiRegistry with one of the
+ *  share() methods.  Shared objects must have a separate interface and implementation.
+ *  The interface is what the other end of the connection will use to interact
+ *  with the object and that interface class must be available on both ends of
+ *  the connection.  The implementing class need only be on the sharing end.</p>
+ *
+ *  <p>Shared objects can be accessed on the other end of the connection by
+ *  using one of the RmiRegistry's getRemoteObject() methods.  These can be
+ *  used to lookup an object by class if it is a shared singleton or by name
+ *  if it was registered with a name.</p>
+ *
+ *  <p>On the hosting side, a special shardGlobal() method is provided that
+ *  will register shared objects that will automatically be provided to every
+ *  new joining client and they will all be calling the same server-side instance.
+ *  Normally, shared objects themselves are connection specific and handled
+ *  at the connection layer.  The shareGlobal() space is a way to have global
+ *  resources passed directly though the need is relatively rare.</p>
+ * 
+ *  <p>Note: This RMI implementation is not as advanced as Java's regular
+ *  RMI as it won't marshall shared references, ie: you can't pass
+ *  a shared objects as an argument to another shared object's method.</p>
  *
  *  @author    Paul Speed
  */
@@ -74,14 +97,34 @@ public class RmiHostedService extends AbstractHostedService {
         Serializer.registerClasses(ClassInfo.class, MethodInfo.class);
     }
 
+    /**
+     *  Shares a server-wide object associated with the specified type.  All connections
+     *  with RMI hosting started will have access to this shared object as soon as they 
+     *  connect and they will all share the same instance.  It is up to the shared object 
+     *  to handle any multithreading that might be required.
+     */     
     public <T> void shareGlobal( T object, Class<? super T> type ) {
         shareGlobal(defaultChannel, type.getName(), object, type);
     }
     
+    /**
+     *  Shares a server-wide object associated with the specified name.  All connections
+     *  with RMI hosting started will have access to this shared object as soon as they 
+     *  connect and they will all share the same instance.  It is up to the shared object 
+     *  to handle any multithreading that might be required.
+     */     
     public <T> void shareGlobal( String name, T object, Class<? super T> type ) {
         shareGlobal(defaultChannel, name, object, type);
     }
     
+    /**
+     *  Shares a server-wide object associated with the specified name over the specified
+     *  channel.  All connections with RMI hosting started will have access to this shared 
+     *  object as soon as they connect and they will all share the same instance.  It is up 
+     *  to the shared object to handle any multithreading that might be required.
+     *  All network communcation associated with the shared object will be done over
+     *  the specified channel. 
+     */     
     public <T> void shareGlobal( byte channel, String name, T object, Class<? super T> type ) {
         GlobalShare share = new GlobalShare(channel, object, type);
         GlobalShare existing = globalShares.put(name, share);
@@ -99,14 +142,30 @@ public class RmiHostedService extends AbstractHostedService {
         }
     } 
 
+    /**
+     *  Set to true if all new connections should automatically have RMI hosting started.
+     *  Set to false if the game-specific connection setup will call startHostingOnConnection()
+     *  after some connection setup is done (for example, logging in).  Note: generally
+     *  is is safe to autohost RMI as long as callers are careful about what they've added
+     *  using shareGlobal().  One reasonable use-case is to shareGlobal() some kind of login
+     *  service and nothing else.  All other shared objects would then be added as connection
+     *  specific objects during successful login processing. 
+     */
     public void setAutoHost( boolean b ) {
         this.autoHost = b;
     }
  
+    /**
+     *  Returns true if RMI hosting is automatically started for all new connections. 
+     */
     public boolean getAutoHost() {
         return autoHost;
     }
 
+    /**
+     *  Returns the RMI registry for the specific HostedConection.  Each connection
+     *  has its own registry with its own connection-specific shared objects.
+     */
     public RmiRegistry getRmiRegistry( HostedConnection hc ) {
         return hc.getAttribute(ATTRIBUTE_NAME);
     }

+ 48 - 5
jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiRegistry.java

@@ -87,18 +87,45 @@ public class RmiRegistry {
         rpc.registerHandler(rmiId, rmiHandler);
     }
     
+    /**
+     *  Exposes the specified object to the other end of the connection as
+     *  the specified interface type.  The object can be looked up by type
+     *  on the other end.
+     */
     public <T> void share( T object, Class<? super T> type ) {
         share(defaultChannel, object, type);       
     }
     
+    /**
+     *  Exposes, through a specific connection channel, the specified object 
+     *  to the other end of the connection as the specified interface type.  
+     *  The object can be looked up by type on the other end.
+     *  The specified channel will be used for all network communication
+     *  specific to this object. 
+     */
     public <T> void share( byte channel, T object, Class<? super T> type ) {
         share(channel, type.getName(), object, type);
     } 
     
+    /**
+     *  Exposes the specified object to the other end of the connection as
+     *  the specified interface type and associates it with the specified name.  
+     *  The object can be looked up by the associated name on the other end of
+     *  the connection.
+     */
     public <T> void share( String name, T object, Class<? super T> type ) {
         share(defaultChannel, name, object, type);
     }
     
+    /**
+     *  Exposes, through a specific connection channel, the specified object to 
+     *  the other end of the connection as the specified interface type and associates 
+     *  it with the specified name.  
+     *  The object can be looked up by the associated name on the other end of
+     *  the connection.
+     *  The specified channel will be used for all network communication
+     *  specific to this object. 
+     */
     public <T> void share( byte channel, String name, T object, Class<? super T> type ) {
         
         ClassInfo typeInfo = classCache.getClassInfo(type);
@@ -153,16 +180,18 @@ public class RmiRegistry {
     }
  
     /**
-     *  Returns an object that was previously registered with share().
+     *  Returns a local object that was previously registered with share() using
+     *  just type registration.
      */
-    public <T> T getSharedObject( Class<T> type ) {
-        return getSharedObject(type.getName(), type);
+    public <T> T getLocalObject( Class<T> type ) {
+        return getLocalObject(type.getName(), type);
     }
     
     /**
-     *  Returns an object that was previously registered with share().
+     *  Returns a local object that was previously registered with share() using
+     *  name registration.
      */
-    public <T> T getSharedObject( String name, Class<T> type ) {
+    public <T> T getLocalObject( String name, Class<T> type ) {
         local.lock.readLock().lock();
         try {
             return type.cast(local.byName.get(name));
@@ -171,10 +200,24 @@ public class RmiRegistry {
         }
     }   
     
+    /**
+     *  Looks up a remote object by type and returns a local proxy to the remote object 
+     *  that was shared on the other end of the network connection.  If this is called 
+     *  from a client then it is accessing a shared object registered on the server.  
+     *  If this is called from the server then it is accessing a shared object registered 
+     *  on the client.
+     */
     public <T> T getRemoteObject( Class<T> type ) {
         return getRemoteObject(type.getName(), type);
     }
 
+    /**
+     *  Looks up a remote object by name and returns a local proxy to the remote object 
+     *  that was shared on the other end of the network connection.  If this is called 
+     *  from a client then it is accessing a shared object registered on the server.  
+     *  If this is called from the server then it is accessing a shared object registered 
+     *  on the client.
+     */
     public <T> T getRemoteObject( String name, Class<T> type ) {
         remote.lock.readLock().lock();
         try {