Class HubConnector
- Direct Known Subclasses:
GuiHubConnector
- Keeps track of other registered clients
- Keeps track of hubs shutting down and starting up
- Manages client metadata and subscription information across hub reconnections
- Facilitates provision of callback services by the client
- Implements simple MTypes such as
samp.app.ping
. - Optionally looks out for hubs starting up and connects automatically when they do
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
- These methods not only make the relevant declarations to the existing hub connection, if one exists, but will retain the metadata and subscriptions information and declare them to other connections if the hub connection is terminated and restarted (with either the same or a different hub) over the lifetime of this object.
callAndWait
- Provides identical semantics to the similarly named
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
- Convenience methods to make asynchronous calls without having to worry about registering handlers which match up message tags.
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.
Examples
Here is an example of what use of this class might look like:// 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.
Backwards Compatibility Note
This class does less than it did in earlier versions; the functionality which is no longer here can now be found in theGuiHubConnector
class instead.- Since:
- 15 Jul 2008
- Author:
- Mark Taylor
-
Constructor Summary
ConstructorsConstructorDescriptionHubConnector
(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. -
Method Summary
Modifier and TypeMethodDescriptionvoid
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
(String recipientId, 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
(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.callAndWait
(String recipientId, Map msg, int timeout) Sends a message synchronously to a client, waiting for the response.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.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
Invoked by this class to create a hub connection.Generates a newmsgTag
for use with this connector.void
declareMetadata
(Map meta) Declares the metadata for this client.void
declareSubscriptions
(Map subscriptions) Declares the MType subscriptions for this client.protected void
Unregisters from the currently connected hub, if any.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
Returns the tracked client set implementation which is used to keep track of the currently registered clients.If necessary attempts to acquire, and returns, a connection to a running hub.Returns this client's own metadata.Returns this client's own subscriptions.boolean
isActive()
Indicates whether this connector is active or not.boolean
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.
-
Constructor Details
-
HubConnector
Constructs a HubConnector based on a given profile instance. A default client set implementation is used.- Parameters:
profile
- profile implementation
-
HubConnector
Constructs a HubConnector based on a given profile instance using a custom client set implementation.- Parameters:
profile
- profile implementationclientSet
- object to keep track of registered clients
-
-
Method Details
-
setAutoconnect
public void setAutoconnect(int autoSec) Sets the interval at which this connector attempts to connect to a hub if no connection currently exists. Otherwise, a connection will be attempted whenevergetConnection()
is called.- Parameters:
autoSec
- number of seconds between attempts; <=0 means no automatic connections are attempted
-
declareMetadata
Declares the metadata for this client. This declaration affects the current connection and any future ones.- Parameters:
meta
-Metadata
-like map
-
getMetadata
Returns this client's own metadata.- Returns:
- metadata
-
declareSubscriptions
Declares the MType subscriptions for this client. This declaration affects the current connection and any future ones.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 callingcomputeSubscriptions()
.- Parameters:
subscriptions
-Subscriptions
-like map
-
getSubscriptions
Returns this client's own subscriptions.- Returns:
- subscriptions
-
computeSubscriptions
Works out the subscriptions map for this connector. This is based on the subscriptions declared by for anyMessageHandler
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 todeclareSubscriptions(java.util.Map)
. However you might wish to remove some entries from the result if there are temporarily unsubscribed services.- Returns:
- subscription list for MTypes apparently implemented by this connector
-
addMessageHandler
Adds a MessageHandler to this connector, which allows it to respond to incoming messages. Note that this does not in itself update the list of subscriptions for this connector; you may want to follow it with a call todeclareSubscriptions(computeSubscriptions());
- Parameters:
handler
- handler to add
-
removeMessageHandler
Removes a previously-added MessageHandler to this connector. Note that this does not in itself update the list of subscriptions for this connector; you may want to follow it with a call todeclareSubscriptions(computeSubscriptions());
- Parameters:
handler
- handler to remove
-
addResponseHandler
Adds a ResponseHandler to this connector, which allows it to receive replies from messages sent asynchronously.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.- Parameters:
handler
- handler to add
-
removeResponseHandler
Removes a ResponseHandler from this connector.- Parameters:
handler
- handler to remove
-
setActive
public void setActive(boolean active) Sets whether this connector is active or not. If set false, any existing connection will be terminated (the client will unregister) and autoconnection attempts will be suspended. If set true, if there is no existing connection an attempt will be made to register, and autoconnection attempts will begin if applicable.- Parameters:
active
- whether this connector should be active- See Also:
-
isActive
public boolean isActive()Indicates whether this connector is active or not.- Returns:
- true if this connector is willing to connect
-
callAndWait
Sends a message synchronously to a client, waiting for the response. If more seconds elapse than the value of thetimeout
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.- Parameters:
recipientId
- public-id of client to receive messagemsg
-Message
-like maptimeout
- timeout in seconds, or <=0 for no timeout- Returns:
- response
- Throws:
SampException
-
call
public void call(String recipientId, Map msg, ResultHandler resultHandler, int timeout) throws SampException Sends a message asynchronously to a single client, making a callback on a supplied ResultHandler object when the result arrives. TheResultHandler.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.
- Parameters:
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 timeout- Throws:
SampException
-
callAll
Sends a message asynchronously to all subscribed clients, making callbacks on a supplied ResultHandler object when the results arrive. TheResultHandler.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.
- Parameters:
msg
-Message
-like mapresultHandler
- object called back when response arrives or timeout is exceededtimeout
- timeout in seconds, or <=0 for no timeout- Throws:
SampException
-
isConnected
public boolean isConnected()Indicates whether this connector is currently registered with a running hub. If true, the result ofgetConnection()
will be non-null.- Returns:
- true if currently connected to a hub
-
getConnection
If necessary attempts to acquire, and returns, a connection to a running hub. If there is an existing connection representing a registration with a hub, it is returned. If not, and this connector is active, an attempt is made to connect and register, followed by a call toconfigureConnection
, is made.Note that if
setActive(false)
has been called, null will be returned.- Returns:
- hub connection representing configured registration with a hub if a hub is running; if not, null
- Throws:
SampException
- in the case of some unexpected error
-
configureConnection
Configures a connection with a hub in accordance with the state of this object. The hub is made aware of how to perform callbacks on the registered client, and any current metadata and subscriptions are declared.- Parameters:
connection
- connection representing registration with a hub- Throws:
SampException
-
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. Map keys are public IDs and values areClient
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 aObject.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 afterdeclareSubscriptions(java.util.Map)
has been called. If this order is not observed, a warning will be emitted through the logging system.- Returns:
- id->Client map
-
getClientSet
Returns the tracked client set implementation which is used to keep track of the currently registered clients.- Returns:
- client set implementation
-
createConnection
Invoked by this class to create a hub connection. The default implementation just callsprofile.register()
.- Returns:
- new hub connection
- Throws:
SampException
-
disconnect
protected void disconnect()Unregisters from the currently connected hub, if any. Performs any associated required cleanup. -
connectionChanged
protected void connectionChanged(boolean isConnected) Method which is called every time this connector changes its connection status (from disconnected to connected, or vice versa). The default implementation does nothing, but it may be overridden by subclasses wishing to be informed of these events.- Parameters:
isConnected
- true if we've just registered; false if we've just unregistered
-
createTag
Generates a newmsgTag
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.- Parameters:
owner
- object to identify caller (not really necessary - may be null)- Returns:
- unique tag for this connector
-