Added a bunch of javadoc and changed the names of one of the
method sets to be a little less confusing.
This commit is contained in:
parent
95aa2d72d0
commit
3a4624a5fe
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -40,7 +40,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Internal registry of shared types and their ClassInfo and MethodInfo
|
||||
* objects.
|
||||
*
|
||||
* @author Paul Speed
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -39,7 +39,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Used internally to remotely invoke methods on RMI shared objects.
|
||||
*
|
||||
* @author Paul Speed
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user