com.threerings.presents.client
Class Client

java.lang.Object
  extended by com.threerings.presents.client.Client
Direct Known Subclasses:
BureauClient

public class Client
extends Object

Through the client object, a connection to the system is established and maintained. The client object maintains two separate threads (a reader and a writer) by which all network traffic is managed.


Nested Class Summary
protected  class Client.ServerSwitcher
          Handles the process of switching between servers.
 
Field Summary
protected  AuthResponseData _authData
          The data associated with our authentication response.
protected  HashSet<String> _bootGroups
          The set of bootstrap service groups this client cares about.
protected  BootstrapData _bstrap
          General startup information provided by the server.
protected  ClientObject _clobj
          Our client distributed object.
protected  int _cloid
          Our client distributed object id.
protected  Communicator _comm
          The entity that manages our network communications.
protected  int _connectionId
          The unique id of our connection.
protected  Credentials _creds
          The credentials we used to authenticate with the server.
protected  int[] _datagramPorts
          The server ports to which we can send datagrams.
protected  DeltaCalculator _dcalc
          Used when establishing our clock delta between the client and server.
protected  String _hostname
          The game server host.
protected  InvocationDirector _invdir
          Manages invocation services.
protected  long _lastSync
          The last time at which we synced our clock with the server.
protected  ClassLoader _loader
          A custom class loader used to load objects that come in over the network.
protected  MessageTracker _messageTracker
          The tracker to notify on message transmission or receipt.
protected  ObserverList<SessionObserver> _observers
          Our list of client observers.
protected  DObjectManager _omgr
          The distributed object manager we're using during this session.
protected  Throttle _outThrottle
          Our outgoing message throttle.
protected  int[] _ports
          The ports on which we connect to the game server.
protected  PublicKey _publicKey
          Our public key.
protected  boolean _requireSecureAuth
          If we require a secure connection to send our credentials.
protected  RunQueue _runQueue
          An entity that gives us the ability to process events on the main client thread.
protected  byte[] _secret
          Our session secret key.
protected  long _serverDelta
          The difference between the server clock and the client clock (estimated immediately after logging on).
protected  boolean _standalone
          Whether or not this client is operating in a standalone mode.
protected  Interval _tickInterval
          Our tick interval id.
protected  String _version
          The version string reported to the server at auth time.
protected static long CLOCK_SYNC_INTERVAL
          How often we recompute our time offset from the server.
static int[] DEFAULT_DATAGRAM_PORTS
          The default ports on which the server listens for datagrams.
static int DEFAULT_MSGS_PER_SECOND
          Our default maximum outgoing message rate in messages per second.
static int[] DEFAULT_SERVER_PORTS
          The default ports on which the server listens for client connections.
static int MAX_DATAGRAM_SIZE
          The maximum size of a datagram.
 
Constructor Summary
Client(Credentials creds, RunQueue runQueue)
          Constructs a client object with the supplied credentials and RunQueue.
 
Method Summary
 void addClientObserver(SessionObserver observer)
          Registers the supplied observer with this client.
 void addServiceGroup(String group)
          Marks this client as interested in the specified bootstrap services group.
protected  void cleanup(Exception logonError)
           
protected  void clientObjectDidChange(ClientObject clobj)
          Called by the invocation director when it discovers that the client object has changed.
protected  void convertFromRemote(DObject target, DEvent event)
          If this client is being used to proxy events from another server, this method can be overridden to adjust the event in any way needed prior to dispatching the event.
protected  Communicator createCommunicator()
          Creates the communicator that this client will use to send and receive messages.
protected  boolean debugLogMessages()
          Whether or not to log low-level debug messages.
protected  void establishClockDelta(long now)
          Called during initialization to initiate a sequence of ping/pong messages which will be used to determine (with "good enough" accuracy) the difference between the client clock and the server clock so that we can later interpret server timestamps.
 void fieldsToString(StringBuilder builder)
          Adds text representation of fields to the builder.
 long fromServerTime(long stamp)
          Converts a server time stamp to a value comparable to client clock readings.
 AuthResponseData getAuthResponseData()
          Returns the data associated with our authentication response.
 String[] getBootGroups()
          Returns the set of bootstrap service groups needed by this client.
 BootstrapData getBootstrapData()
          Returns a reference to the bootstrap data provided to this client at logon time.
 ClientObject getClientObject()
          Returns a reference to the client object associated with this session.
protected  void getClientObjectFailed(Exception cause)
          Called by the invocation director if it fails to subscribe to the client object after logon.
 int getClientOid()
          Returns the oid of the client object associated with this session.
 int getConnectionId()
          Returns the unique id of the client's connection to the server.
 Credentials getCredentials()
          Returns the credentials with which this client is currently configured to connect to the server.
 int[] getDatagramPorts()
          Returns the ports on the server to which the client can send datagrams.
 DObjectManager getDObjectManager()
          Returns the distributed object manager associated with this session.
 String getHostname()
          Returns the hostname of the server to which this client is currently configured to connect.
 InvocationDirector getInvocationDirector()
          Returns the invocation director associated with this session.
protected  MessageTracker getMessageTracker()
          Returns a reference to the message tracker to notify on message transmission and receipt.
protected  Throttle getOutgoingMessageThrottle()
          Returns our outgoing message throttle.
 int[] getPorts()
          Returns the port on which this client is currently configured to connect to the server.
 PublicKey getPublicKey()
          Returns the public key with which this client is currently configured to create a secure authentication channel to the server.
 RunQueue getRunQueue()
          Returns the RunQueue in use by this client.
 byte[] getSecret()
          Gets the secret key to use with a session.
<T> T
getService(Class<T> sclass)
          Returns the first bootstrap service that could be located that implements the supplied InvocationService derivation.
 boolean getTransmitDatagrams()
          Checks whether we should transmit datagrams.
 String getVersion()
          Returns the version string configured for this client.
protected  void gotBootstrap(BootstrapData data, DObjectManager omgr)
          Called by the ClientDObjectMgr when our bootstrap notification arrives.
protected  void gotClientObject(ClientObject clobj)
          Called by the invocation director when it successfully subscribes to the client object immediately following logon.
protected  void gotPong(PongResponse pong)
          Called when we receive a pong packet.
 boolean isActive()
          Returns true if we are in active communication (we may not yet be logged on, but we could be trying to log on).
 boolean isLoggedOn()
          Returns true if we are logged on, false if we're not.
 boolean isStandalone()
          Checks whether or not this client is operating in a standalone mode.
 boolean logoff(boolean abortable)
          Requests that the client log off of the server to which it is connected.
 boolean logon()
          Requests that this client connect and logon to the server with which it was previously configured.
 void moveToServer(String hostname, int[] ports, int[] datagramPorts, InvocationService.ConfirmListener obs)
          Transitions a logged on client from its current server to the specified new server.
 void moveToServer(String hostname, int[] ports, InvocationService.ConfirmListener obs)
          Transitions a logged on client from its current server to the specified new server.
protected  void notifyObservers(ObserverOps.Session op)
           
 String[] prepareStandaloneLogon()
          Prepares the client for a standalone mode logon.
 void registerFlushDelay(Class<?> objclass, long delay)
          Instructs the distributed object manager associated with this client to allow objects of the specified class to linger around the specified number of milliseconds after their last subscriber has been removed before the client finally removes its object proxy and flushes the object.
 void removeClientObserver(SessionObserver observer)
          Unregisters the supplied observer.
protected  void reportLogonTribulations(LogonException cause)
          Called by the Communicator if it is experiencing trouble logging on but is still trying fallback strategies.
 boolean requireSecureAuth()
          Returns true if we require secure authentication.
<T> T
requireService(Class<T> sclass)
          Like getService(java.lang.Class) except that a RuntimeException is thrown if the service is not available.
 void setClassLoader(ClassLoader loader)
          Configures the client with a custom class loader which will be used when reading objects off of the network.
 void setCredentials(Credentials creds)
          Sets the credentials that will be used by this client to authenticate with the server.
 void setMessageTracker(MessageTracker tracker)
          Installs (or clears) a message tracker that will be notified on message transmission and receipt for the purpose of statistics tracking.
protected  void setOutgoingMessageThrottle(int msgsPerSec)
          Configures the outgoing message throttle.
 boolean setPublicKey(PublicKey key)
          Sets the public key that will be used by this client to create a secure authentication channel with the server if the ciphers are supported.
 boolean setPublicKey(String key)
          Sets the public key that will be used by this client to create a secure authentication channel with the server if the ciphers are supported.
 void setRequireSecureAuth(boolean requireSecureAuth)
          Sets if we require a secure authentication.
 void setSecret(byte[] secret)
          Sets the secret key to use with a session.
 void setServer(String hostname, int[] ports)
          Configures the client to communicate with the server on the supplied hostname and set of ports (which will be tried in succession).
 void setServer(String hostname, int[] ports, int[] datagramPorts)
          Configures the client to communicate with the server on the supplied hostname, set of ports (which will be tried in succession), and datagram ports.
 void setVersion(String version)
          Sets the version string reported to the server during authentication.
 void standaloneLogoff()
          For standalone mode, this notifies observers that the client has logged off and cleans up.
 void standaloneLogon(BootstrapData data, DObjectManager omgr)
          Logs this client on in standalone mode with the faked bootstrap data and shared local distributed object manager.
protected  void tick()
          Called every five seconds; ensures that we ping the server if we haven't communicated in a long while and periodically resyncs the client and server clock deltas.
 long toServerTime(long stamp)
          Converts a client clock reading to a value comparable to a server time stamp.
 String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_SERVER_PORTS

public static final int[] DEFAULT_SERVER_PORTS
The default ports on which the server listens for client connections.


DEFAULT_DATAGRAM_PORTS

public static final int[] DEFAULT_DATAGRAM_PORTS
The default ports on which the server listens for datagrams.


MAX_DATAGRAM_SIZE

public static final int MAX_DATAGRAM_SIZE
The maximum size of a datagram.

See Also:
Constant Field Values

DEFAULT_MSGS_PER_SECOND

public static final int DEFAULT_MSGS_PER_SECOND
Our default maximum outgoing message rate in messages per second.

See Also:
Constant Field Values

_creds

protected Credentials _creds
The credentials we used to authenticate with the server.


_version

protected String _version
The version string reported to the server at auth time.


_runQueue

protected RunQueue _runQueue
An entity that gives us the ability to process events on the main client thread.


_omgr

protected DObjectManager _omgr
The distributed object manager we're using during this session.


_authData

protected AuthResponseData _authData
The data associated with our authentication response.


_publicKey

protected PublicKey _publicKey
Our public key.


_secret

protected byte[] _secret
Our session secret key.


_requireSecureAuth

protected boolean _requireSecureAuth
If we require a secure connection to send our credentials.


_connectionId

protected int _connectionId
The unique id of our connection.


_cloid

protected int _cloid
Our client distributed object id.


_clobj

protected ClientObject _clobj
Our client distributed object.


_standalone

protected boolean _standalone
Whether or not this client is operating in a standalone mode.


_hostname

protected String _hostname
The game server host.


_ports

protected int[] _ports
The ports on which we connect to the game server.


_datagramPorts

protected int[] _datagramPorts
The server ports to which we can send datagrams.


_observers

protected ObserverList<SessionObserver> _observers
Our list of client observers.


_comm

protected Communicator _comm
The entity that manages our network communications.


_loader

protected ClassLoader _loader
A custom class loader used to load objects that come in over the network.


_bstrap

protected BootstrapData _bstrap
General startup information provided by the server.


_bootGroups

protected HashSet<String> _bootGroups
The set of bootstrap service groups this client cares about.


_invdir

protected InvocationDirector _invdir
Manages invocation services.


_serverDelta

protected long _serverDelta
The difference between the server clock and the client clock (estimated immediately after logging on).


_dcalc

protected DeltaCalculator _dcalc
Used when establishing our clock delta between the client and server.


_lastSync

protected long _lastSync
The last time at which we synced our clock with the server.


_tickInterval

protected Interval _tickInterval
Our tick interval id.


_outThrottle

protected Throttle _outThrottle
Our outgoing message throttle.


_messageTracker

protected volatile MessageTracker _messageTracker
The tracker to notify on message transmission or receipt.


CLOCK_SYNC_INTERVAL

protected static final long CLOCK_SYNC_INTERVAL
How often we recompute our time offset from the server.

See Also:
Constant Field Values
Constructor Detail

Client

public Client(Credentials creds,
              RunQueue runQueue)
Constructs a client object with the supplied credentials and RunQueue. The creds will be used to authenticate with any server to which this client attempts to connect. The RunQueue is used to operate the distributed object event dispatch mechanism. To allow the dobj event dispatch to coexist with threads like the AWT thread, the client will request that the RunQueue queue up a runnable whenever there are distributed object events that need to be processed. The RunQueue can then queue that runnable up on the AWT thread if it is so inclined to make life simpler for the rest of the application.

Parameters:
creds - the credentials to use when logging on to the server. These can be null, but setCredentials must then be called before any call to logon.
runQueue - a RunQueue that can be used to process incoming events.
Method Detail

addClientObserver

public void addClientObserver(SessionObserver observer)
Registers the supplied observer with this client. While registered the observer will receive notifications of state changes within the client. The function will refuse to register an already registered observer.

See Also:
ClientObserver, SessionObserver

removeClientObserver

public void removeClientObserver(SessionObserver observer)
Unregisters the supplied observer. Upon return of this function, the observer will no longer receive notifications of state changes within the client.


isStandalone

public boolean isStandalone()
Checks whether or not this client is operating in a standalone mode.


setServer

public void setServer(String hostname,
                      int[] ports)
Configures the client to communicate with the server on the supplied hostname and set of ports (which will be tried in succession).

See Also:
logon(), moveToServer(java.lang.String, int[], com.threerings.presents.client.InvocationService.ConfirmListener)

setServer

public void setServer(String hostname,
                      int[] ports,
                      int[] datagramPorts)
Configures the client to communicate with the server on the supplied hostname, set of ports (which will be tried in succession), and datagram ports.

See Also:
logon(), moveToServer(java.lang.String, int[], com.threerings.presents.client.InvocationService.ConfirmListener)

getRunQueue

public RunQueue getRunQueue()
Returns the RunQueue in use by this client. This can be used to queue up event dispatching stints.


getHostname

public String getHostname()
Returns the hostname of the server to which this client is currently configured to connect.


getPorts

public int[] getPorts()
Returns the port on which this client is currently configured to connect to the server.


getDatagramPorts

public int[] getDatagramPorts()
Returns the ports on the server to which the client can send datagrams. Returns an empty array if datagrams are not supported.


getCredentials

public Credentials getCredentials()
Returns the credentials with which this client is currently configured to connect to the server.


setCredentials

public void setCredentials(Credentials creds)
Sets the credentials that will be used by this client to authenticate with the server. This should be done before any call to logon.


getPublicKey

public PublicKey getPublicKey()
Returns the public key with which this client is currently configured to create a secure authentication channel to the server.


setPublicKey

public boolean setPublicKey(PublicKey key)
Sets the public key that will be used by this client to create a secure authentication channel with the server if the ciphers are supported. This should be done before any call to logon.

Returns:
true if the key is set

setPublicKey

public boolean setPublicKey(String key)
Sets the public key that will be used by this client to create a secure authentication channel with the server if the ciphers are supported. This should be done before any call to logon.

Returns:
true if the key is set

setRequireSecureAuth

public void setRequireSecureAuth(boolean requireSecureAuth)
Sets if we require a secure authentication.


requireSecureAuth

public boolean requireSecureAuth()
Returns true if we require secure authentication.


setSecret

public void setSecret(byte[] secret)
Sets the secret key to use with a session.


getSecret

public byte[] getSecret()
Gets the secret key to use with a session.


getVersion

public String getVersion()
Returns the version string configured for this client.


setVersion

public void setVersion(String version)
Sets the version string reported to the server during authentication. Some server implementations may wish to refuse connections by old or invalid client versions.


setClassLoader

public void setClassLoader(ClassLoader loader)
Configures the client with a custom class loader which will be used when reading objects off of the network.


setMessageTracker

public void setMessageTracker(MessageTracker tracker)
Installs (or clears) a message tracker that will be notified on message transmission and receipt for the purpose of statistics tracking.

Parameters:
tracker - the new tracker to install, or null to clear the tracker.

getAuthResponseData

public AuthResponseData getAuthResponseData()
Returns the data associated with our authentication response. Users of the Presents system may wish to communicate authentication related information to their client by extending and augmenting AuthResponseData.


getDObjectManager

public DObjectManager getDObjectManager()
Returns the distributed object manager associated with this session. This reference is only valid for the duration of the session and a new reference must be obtained if the client disconnects and reconnects to the server.

Returns:
the dobjmgr in effect or null if we have no established connection to the server.

registerFlushDelay

public void registerFlushDelay(Class<?> objclass,
                               long delay)
Instructs the distributed object manager associated with this client to allow objects of the specified class to linger around the specified number of milliseconds after their last subscriber has been removed before the client finally removes its object proxy and flushes the object. Normally, objects are flushed immediately following the removal of their last subscriber.

Note: the delay will be applied to derived classes as well as exact matches. Note also: this method cannot be called until after the client has established a connection with the server and the distributed object manager is available.


getConnectionId

public int getConnectionId()
Returns the unique id of the client's connection to the server. It is only valid for the duration of the session.


getClientOid

public int getClientOid()
Returns the oid of the client object associated with this session. It is only valid for the duration of the session.


getClientObject

public ClientObject getClientObject()
Returns a reference to the client object associated with this session. It is only valid for the duration of the session.


getInvocationDirector

public InvocationDirector getInvocationDirector()
Returns the invocation director associated with this session. This reference is only valid for the duration of the session.


addServiceGroup

public void addServiceGroup(String group)
Marks this client as interested in the specified bootstrap services group. Any services registered as bootstrap services with the supplied group name will be included in this clients bootstrap services set. This must be called before logon().


getBootGroups

public String[] getBootGroups()
Returns the set of bootstrap service groups needed by this client.


getService

public <T> T getService(Class<T> sclass)
Returns the first bootstrap service that could be located that implements the supplied InvocationService derivation. null is returned if no such service could be found.


requireService

public <T> T requireService(Class<T> sclass)
Like getService(java.lang.Class) except that a RuntimeException is thrown if the service is not available. Useful to avoid redundant error checking when you know that the shit will hit the fan if a particular invocation service is not available.


getBootstrapData

public BootstrapData getBootstrapData()
Returns a reference to the bootstrap data provided to this client at logon time.


fromServerTime

public long fromServerTime(long stamp)
Converts a server time stamp to a value comparable to client clock readings.


toServerTime

public long toServerTime(long stamp)
Converts a client clock reading to a value comparable to a server time stamp.


isActive

public boolean isActive()
Returns true if we are in active communication (we may not yet be logged on, but we could be trying to log on).


getTransmitDatagrams

public boolean getTransmitDatagrams()
Checks whether we should transmit datagrams.


isLoggedOn

public boolean isLoggedOn()
Returns true if we are logged on, false if we're not.


logon

public boolean logon()
Requests that this client connect and logon to the server with which it was previously configured.

Returns:
false if we're already logged on, true if a logon attempt was initiated.

moveToServer

public void moveToServer(String hostname,
                         int[] ports,
                         InvocationService.ConfirmListener obs)
Transitions a logged on client from its current server to the specified new server. Currently this simply logs the client off of its current server (if it is logged on) and logs it onto the new server, but in the future we may aim to do something fancier.

If we fail to connect to the new server, the client will not be automatically reconnected to the old server. It will be in a logged off state. However, it will be reconfigured with the hostname and ports of the old server so that the caller can notify the user of the failure and then simply call logon() to attempt to reconnect to the old server.

Parameters:
obs - an observer that will be notified when we have successfully logged onto the other server, or if the move failed.

moveToServer

public void moveToServer(String hostname,
                         int[] ports,
                         int[] datagramPorts,
                         InvocationService.ConfirmListener obs)
Transitions a logged on client from its current server to the specified new server. Currently this simply logs the client off of its current server (if it is logged on) and logs it onto the new server, but in the future we may aim to do something fancier.

If we fail to connect to the new server, the client will not be automatically reconnected to the old server. It will be in a logged off state. However, it will be reconfigured with the hostname and ports of the old server so that the caller can notify the user of the failure and then simply call logon() to attempt to reconnect to the old server.

Parameters:
obs - an observer that will be notified when we have successfully logged onto the other server, or if the move failed.

logoff

public boolean logoff(boolean abortable)
Requests that the client log off of the server to which it is connected.

Parameters:
abortable - If true, the client will call clientWillDisconnect on all of the client observers and abort the logoff process if any of them return false. If false, clientWillDisconnect will not be called at all.
Returns:
true if the logoff succeeded, false if it failed due to a disagreeable observer.

prepareStandaloneLogon

public String[] prepareStandaloneLogon()
Prepares the client for a standalone mode logon. Returns the set of bootstrap service groups that should be supplied to the invocation manager to create our fake bootstrap record.


standaloneLogon

public void standaloneLogon(BootstrapData data,
                            DObjectManager omgr)
Logs this client on in standalone mode with the faked bootstrap data and shared local distributed object manager.


standaloneLogoff

public void standaloneLogoff()
For standalone mode, this notifies observers that the client has logged off and cleans up.


toString

public String toString()
Overrides:
toString in class Object

fieldsToString

public void fieldsToString(StringBuilder builder)
Adds text representation of fields to the builder. The results will be placed between brackets by toString.


gotBootstrap

protected void gotBootstrap(BootstrapData data,
                            DObjectManager omgr)
Called by the ClientDObjectMgr when our bootstrap notification arrives. If the client and server are being run in "merged" mode in a single JVM, this is how the client is configured with the server's distributed object manager and provided with bootstrap data.


convertFromRemote

protected void convertFromRemote(DObject target,
                                 DEvent event)
If this client is being used to proxy events from another server, this method can be overridden to adjust the event in any way needed prior to dispatching the event.


createCommunicator

protected Communicator createCommunicator()
Creates the communicator that this client will use to send and receive messages.


setOutgoingMessageThrottle

protected void setOutgoingMessageThrottle(int msgsPerSec)
Configures the outgoing message throttle. This is done when the server informs us that a new rate is in effect.


getOutgoingMessageThrottle

protected Throttle getOutgoingMessageThrottle()
Returns our outgoing message throttle. Used by the communicator's writer.


getMessageTracker

protected MessageTracker getMessageTracker()
Returns a reference to the message tracker to notify on message transmission and receipt.


tick

protected void tick()
Called every five seconds; ensures that we ping the server if we haven't communicated in a long while and periodically resyncs the client and server clock deltas.


establishClockDelta

protected void establishClockDelta(long now)
Called during initialization to initiate a sequence of ping/pong messages which will be used to determine (with "good enough" accuracy) the difference between the client clock and the server clock so that we can later interpret server timestamps.


reportLogonTribulations

protected void reportLogonTribulations(LogonException cause)
Called by the Communicator if it is experiencing trouble logging on but is still trying fallback strategies.


gotClientObject

protected void gotClientObject(ClientObject clobj)
Called by the invocation director when it successfully subscribes to the client object immediately following logon.


getClientObjectFailed

protected void getClientObjectFailed(Exception cause)
Called by the invocation director if it fails to subscribe to the client object after logon.


clientObjectDidChange

protected void clientObjectDidChange(ClientObject clobj)
Called by the invocation director when it discovers that the client object has changed.


notifyObservers

protected void notifyObservers(ObserverOps.Session op)

cleanup

protected void cleanup(Exception logonError)

gotPong

protected void gotPong(PongResponse pong)
Called when we receive a pong packet. We may be in the process of calculating the client/ server time differential, or we may have already done that at which point we ignore pongs.


debugLogMessages

protected boolean debugLogMessages()
Whether or not to log low-level debug messages. This is used by the communicator as well which may be running on the server as a peer client, so we want to avoid constructing log messages when we're not logging and thus need to use this pattern rather than just log.fine.