public class HubConnector
extends java.lang.Object
samp.app.ping
.
This object provides a getConnection()
method which provides
the currently active HubConnection
object if one exists or can be
acquired. The HubConnection
can be used for direct calls
on the running hub, but in some cases similar methods with additional
functionality exist in this class:
declareMetadata
declareSubscriptions
callAndWait
HubConnection
method, but communicates with the hub
asynchronously and fakes the synchrony at the client end.
This is more robust and almost certainly a better idea.
call
callAll
It is good practice to call setActive(false)
when this object is finished with; however if it is not called
explicitly, any open connection will unregister itself on
object finalisation or JVM termination, as long as the JVM shuts
down cleanly.
// Construct a connector ClientProfile profile = DefaultClientProfile.getProfile(); HubConnector conn = new HubConnector(profile) // Configure it with metadata about this application Metadata meta = new Metadata(); meta.setName("Foo"); meta.setDescriptionText("Application that does stuff"); conn.declareMetadata(meta); // Prepare to receive messages with specific MType(s) conn.addMessageHandler(new AbstractMessageHandler("stuff.do") { public Map processCall(HubConnection c, String senderId, Message msg) { // do stuff } }); // This step required even if no custom message handlers added. conn.declareSubscriptions(conn.computeSubscriptions()); // Keep a look out for hubs if initial one shuts down conn.setAutoconnect(10); // Broadcast a message conn.getConnection().notifyAll(new Message("stuff.event.doing"));
A real example, including use of the GUI hooks, can be found in the
HubMonitor
client source code.
GuiHubConnector
class instead.Modifier and Type | Class and Description |
---|---|
private class |
HubConnector.CallHandler
ResponseHandler which looks after responses made by calls using the
call() and callAll() convenience methods.
|
private class |
HubConnector.CallItem
Stores state about a particular set of responses expected by the
CallHandler class.
|
private class |
HubConnector.ConnectorCallableClient
CallableClient implementation used by this class.
|
Modifier and Type | Field and Description |
---|---|
private int |
autoSec_ |
private HubConnector.ConnectorCallableClient |
callable_ |
private HubConnector.CallHandler |
callHandler_ |
private TrackedClientSet |
clientSet_ |
private ClientTracker |
clientTracker_ |
private HubConnection |
connection_ |
private static java.lang.String |
DISCONNECT_MTYPE |
private static java.lang.String |
GETENV_MTYPE |
private int |
iCall_ |
private boolean |
isActive_ |
private java.util.logging.Logger |
logger_ |
private java.util.List |
messageHandlerList_ |
private Metadata |
metadata_ |
private static java.lang.String |
PING_MTYPE |
private ClientProfile |
profile_ |
private java.util.Timer |
regTimer_ |
private java.util.List |
responseHandlerList_ |
private java.util.Map |
responseMap_ |
private static java.lang.String |
SHUTDOWN_MTYPE |
private Subscriptions |
subscriptions_ |
Constructor and Description |
---|
HubConnector(ClientProfile profile)
Constructs a HubConnector based on a given profile instance.
|
HubConnector(ClientProfile profile,
TrackedClientSet clientSet)
Constructs a HubConnector based on a given profile instance
using a custom client set implementation.
|
Modifier and Type | Method and Description |
---|---|
void |
addMessageHandler(MessageHandler handler)
Adds a MessageHandler to this connector, which allows it to respond
to incoming messages.
|
void |
addResponseHandler(ResponseHandler handler)
Adds a ResponseHandler to this connector, which allows it to receive
replies from messages sent asynchronously.
|
void |
call(java.lang.String recipientId,
java.util.Map msg,
ResultHandler resultHandler,
int timeout)
Sends a message asynchronously to a single client, making a callback
on a supplied ResultHandler object when the result arrives.
|
void |
callAll(java.util.Map msg,
ResultHandler resultHandler,
int timeout)
Sends a message asynchronously to all subscribed clients,
making callbacks on a supplied ResultHandler object when the
results arrive.
|
Response |
callAndWait(java.lang.String recipientId,
java.util.Map msg,
int timeout)
Sends a message synchronously to a client, waiting for the response.
|
private void |
checkHubMessage(HubConnection connection,
java.lang.String senderId,
java.lang.String mtype)
Performs sanity checking on a message which is normally expected to
be sent only by the hub client itself.
|
Subscriptions |
computeSubscriptions()
Works out the subscriptions map for this connector.
|
void |
configureConnection(HubConnection connection)
Configures a connection with a hub in accordance with the state of
this object.
|
private void |
configureRegisterTimer(int autoSec)
Configures a timer thread to attempt registration periodically.
|
protected void |
connectionChanged(boolean isConnected)
Method which is called every time this connector changes its connection
status (from disconnected to connected, or vice versa).
|
protected HubConnection |
createConnection()
Invoked by this class to create a hub connection.
|
java.lang.String |
createTag(java.lang.Object owner)
Generates a new
msgTag for use with this connector. |
void |
declareMetadata(java.util.Map meta)
Declares the metadata for this client.
|
void |
declareSubscriptions(java.util.Map subscriptions)
Declares the MType subscriptions for this client.
|
protected void |
disconnect()
Unregisters from the currently connected hub, if any.
|
java.util.Map |
getClientMap()
Returns a map which keeps track of other clients currently registered
with the hub to which this object is connected, including their
currently declared metadata and subscriptions.
|
protected TrackedClientSet |
getClientSet()
Returns the tracked client set implementation which is used to keep
track of the currently registered clients.
|
HubConnection |
getConnection()
If necessary attempts to acquire, and returns, a connection to a
running hub.
|
Metadata |
getMetadata()
Returns this client's own metadata.
|
Subscriptions |
getSubscriptions()
Returns this client's own subscriptions.
|
boolean |
isConnected()
Indicates whether this connector is currently registered with a
running hub.
|
void |
removeMessageHandler(MessageHandler handler)
Removes a previously-added MessageHandler to this connector.
|
void |
removeResponseHandler(ResponseHandler handler)
Removes a ResponseHandler from this connector.
|
void |
setActive(boolean active)
Sets whether this connector is active or not.
|
void |
setAutoconnect(int autoSec)
Sets the interval at which this connector attempts to connect to a
hub if no connection currently exists.
|
private final ClientProfile profile_
private final TrackedClientSet clientSet_
private final java.util.List messageHandlerList_
private final java.util.List responseHandlerList_
private final HubConnector.ConnectorCallableClient callable_
private final java.util.Map responseMap_
private final ClientTracker clientTracker_
private final HubConnector.CallHandler callHandler_
private volatile boolean isActive_
private volatile HubConnection connection_
private volatile Metadata metadata_
private volatile Subscriptions subscriptions_
private volatile int autoSec_
private volatile java.util.Timer regTimer_
private volatile int iCall_
private final java.util.logging.Logger logger_
private static final java.lang.String SHUTDOWN_MTYPE
private static final java.lang.String DISCONNECT_MTYPE
private static final java.lang.String PING_MTYPE
private static final java.lang.String GETENV_MTYPE
public HubConnector(ClientProfile profile)
profile
- profile implementationpublic HubConnector(ClientProfile profile, TrackedClientSet clientSet)
profile
- profile implementationclientSet
- object to keep track of registered clientspublic void setAutoconnect(int autoSec)
getConnection()
is called.autoSec
- number of seconds between attempts;
<=0 means no automatic connections are attemptedprivate void configureRegisterTimer(int autoSec)
autoSec
- number of seconds between attempts;
<=0 means no automatic connections are attemptedpublic void declareMetadata(java.util.Map meta)
meta
- Metadata
-like mappublic Metadata getMetadata()
public void declareSubscriptions(java.util.Map subscriptions)
Note that this call must be made, with a subscription list
which includes the various hub administrative messages, in order
for this connector to act on those messages (for instance to
update its client map and so on). For this reason, it is usual
to call it with the subs
argument given by
the result of calling computeSubscriptions()
.
subscriptions
- Subscriptions
-like mappublic Subscriptions getSubscriptions()
public Subscriptions computeSubscriptions()
MessageHandler
s installed in this connector as well as
any MTypes which this connector implements internally.
The result of this method is usually a suitable value to pass
to declareSubscriptions(java.util.Map)
. However you might wish to
remove some entries from the result if there are temporarily
unsubscribed services.public void addMessageHandler(MessageHandler handler)
declareSubscriptions(computeSubscriptions());
handler
- handler to addpublic void removeMessageHandler(MessageHandler handler)
declareSubscriptions(computeSubscriptions());
handler
- handler to removepublic void addResponseHandler(ResponseHandler handler)
Note however that this class's callAndWait
method
can provide a synchronous facade for fully asynchronous messaging,
which in many cases will be more convenient than installing your
own response handlers to deal with asynchronous replies.
handler
- handler to addpublic void removeResponseHandler(ResponseHandler handler)
handler
- handler to removepublic void setActive(boolean active)
active
- whether this connector should be activesetAutoconnect(int)
public Response callAndWait(java.lang.String recipientId, java.util.Map msg, int timeout) throws SampException
timeout
parameter, an exception will result.
The semantics of this call are, as far as the caller is concerned,
identical to that of the similarly named HubConnection
method.
However, in this case the client communicates with the hub
asynchronously and internally simulates the synchrony for the caller,
rather than letting the hub do that.
This is more robust and almost certainly a better idea.
recipientId
- public-id of client to receive messagemsg
- Message
-like maptimeout
- timeout in seconds, or <=0 for no timeoutSampException
public void call(java.lang.String recipientId, java.util.Map msg, ResultHandler resultHandler, int timeout) throws SampException
ResultHandler.done()
method will
be called after the result has arrived or the timeout elapses,
whichever happens first.
This convenience method allows the user to make an asynchronous call without having to worry registering message handlers and matching message tags.
recipientId
- public-id of client to receive messagemsg
- Message
-like mapresultHandler
- object called back when response arrives or
timeout is exceededtimeout
- timeout in seconds, or <=0 for no timeoutSampException
public void callAll(java.util.Map msg, ResultHandler resultHandler, int timeout) throws SampException
ResultHandler.done()
method will
be called after all the results have arrived or the timeout elapses,
whichever happens first.
This convenience method allows the user to make an asynchronous call without having to worry registering message handlers and matching message tags.
msg
- Message
-like mapresultHandler
- object called back when response arrives or
timeout is exceededtimeout
- timeout in seconds, or <=0 for no timeoutSampException
public boolean isConnected()
getConnection()
will be non-null.public HubConnection getConnection() throws SampException
configureConnection
, is made.
Note that if setActive(false)
has been called,
null will be returned.
SampException
- in the case of some unexpected errorpublic void configureConnection(HubConnection connection) throws SampException
connection
- connection representing registration with a hubSampException
public java.util.Map getClientMap()
Client
s.
This map is synchronized
which means that to iterate over any of its views
you must synchronize on it.
When the map or any of its contents changes, it will receive a
Object.notifyAll()
.
To keep itself up to date, the client map reads hub status messages.
These will only be received if
declareSubscriptions(computeSubscriptions())
has been
called.
Hence, this method should only be called after
declareSubscriptions(java.util.Map)
has been called.
If this order is not observed, a warning will be emitted through
the logging system.
protected TrackedClientSet getClientSet()
protected HubConnection createConnection() throws SampException
profile.register()
.SampException
protected void disconnect()
protected void connectionChanged(boolean isConnected)
isConnected
- true if we've just registered;
false if we've just unregisteredprivate void checkHubMessage(HubConnection connection, java.lang.String senderId, java.lang.String mtype)
connection
- connection to the hubsenderId
- public client id of sendermtype
- MType of sent messagepublic java.lang.String createTag(java.lang.Object owner)
msgTag
for use with this connector.
It is guaranteed to return a different value on each invocation.
It is advisable to use this method whenever a message tag is required
to prevent clashes.owner
- object to identify caller
(not really necessary - may be null)