17.12. Handling Private events
Handling Private events is almost identical to handling Replacing or Queueing events. In this description, most things are repeated, and differences are noted explicitly.
A client application subscribes to a Private event by calling the following method of the ClientEndpoint class:
public void subscribeToPEvent(String eventName, RemoteEventListener listener)
The difference from the subscription method of Replacing or Queueing events is only in the name of the method. It has the same two parameters:
- eventName is the event name described in the previous section;
- listener is an event listener of type RemoteEventListener.
The application provides the event name and implementation of the RemoteEventListener interface to the method call. The interface declares two methods to implement:
public interface RemoteEventListener {
void accept(ClientEndpoint clientEndpoint, RemoteEvent remoteEvent);
void acceptError(ClientEndpoint clientEndpoint, SoftnetException exception);
}
The first method, accept, is an event handler. It is called by the endpoint when it receives an event. As with Replacing events, the endpoint receives the next event only after the current call to the handler has completed. The method has two parameters:
- clientEndpoint is the endpoint that called the handler;
- remoteEvent of type RemoteEvent is the received event.
The second method, acceptError, is called in case of an error. Currently, the only possible error can be caused by subscribing to a non-existent event.
The next is a description of the RemoteEvent fields. In contrast to another two categories of events, here the category field is set to Private and the isNull field is not used:
public class RemoteEvent {
public final String name;
public final EventCategory category;
public final boolean isNull;
public final long serviceId;
public final long age;
public final java.util.Date createdDate;
public final SequenceDecoder arguments;
}
- name is the event name specified in the event subscription;
- category is of type EventCategory enumeration. For Private events, it is set to Private;
- isNull is not used;
- serviceId is an ID of the remote service raised the event. To get the appropriate object of type RemoteService, call the client endpoint’s findService method that expects the service ID as an argument;
- age specifies the time in seconds elapsed since the event has been received by the broker. This value is zero if the event is sent to the client without delay as soon as it is received by the broker;
- createdDate specifies the date and time when the event has been received by the broker;
- arguments is of type SequenceDecoder provided by Softnet ASN.1 Codec. It contains data attached to the event by the service.
We conclude this section with an example that demonstrates how to both subscribe to and handle the Private event raised in the example of the previous section.
The code below creates the client endpoint using the arguments provided in the args parameter of the main method. Then it creates a subscription to the “WaterTemperatureSet” event and provides the event handler to the subscribeToPEvent method. The handler’s accept method has a remoteEvent parameter that represents the event itself. It has an arguments field that provides the current temperature passed in by the service. This is the actual temperature after the target temperature setting process is completed. After creating the subscription and defining the event handler, the example code calls the “SetWaterTemperature” RPC method, which starts the process of setting the target temperature on the remote service. In the RPC response handler, the client immediately receives the current temperature at the time the process is started.
public static void main(String[] args) {
ClientSEndpoint clientSEndpoint = null;
try {
String client_uri = args[0];
String password = args[1];
ClientURI clientURI = new ClientURI(client_uri);
clientSEndpoint = ClientSEndpoint.create("Water Boiler", "Softnet Team", clientURI, password);
clientSEndpoint.setPersistenceL2();
clientSEndpoint.subscribeToPEvent("WaterTemperatureSet", new RemoteEventListener() {
public void accept(ClientEndpoint clientEndpoint, RemoteEvent remoteEvent) {
try {
System.out.println(String.format(
"The event '%s' is received.",
remoteEvent.name));
System.out.println(String.format(
"The temperature is set to '%d' degrees Celsius.",
remoteEvent.arguments.Int32()));
}
catch(Exception ex) {
System.out.println(String.format(
"Event data format error: %s",
ex.getMessage()));
}
}
public void acceptError(ClientEndpoint clientEndpoint, SoftnetException exception) {
System.out.println(String.format(
"Subscription error: %s",
exception.getMessage()));
}
});
clientSEndpoint.addEventListener(new ClientEventAdapter() {
@Override
public void onStatusChanged(ClientEndpointEvent e) {
ClientSEndpoint clientSEndpoint = (ClientSEndpoint)e.getEndpoint();
if(clientSEndpoint.isOnline() && clientSEndpoint.isServiceOnline())
makeRpcRequest(clientSEndpoint);
}
@Override
public void onServiceOnline(RemoteServiceEvent e) {
ClientSEndpoint clientSEndpoint = (ClientSEndpoint)e.getEndpoint();
makeRpcRequest(clientSEndpoint);
}
void makeRpcRequest(ClientSEndpoint clientSEndpoint) {
RemoteProcedure remoteProcedure = new RemoteProcedure("SetWaterTemperature");
clientSEndpoint.call(remoteProcedure, new RPCResponseHandler() {
public void onSuccess(ResponseContext context, SequenceDecoder result) {
try {
System.out.println("Establishing the target temperature is started.");
System.out.println("The service will notify you when the process is completed.");
System.out.println(String.format(
"The current temperature is '%d' degrees Celsius.",
result.Int32()));
}
catch(Exception ex) {
System.out.println(String.format(
"Event data format error: %s",
ex.getMessage()));
}
}
public void onError(ResponseContext context, int errorCode, SequenceDecoder error) { }
public void onError(ResponseContext context, SoftnetException exception) { }
});
}
});
clientSEndpoint.connect();
System.in.read();
}
catch(java.io.IOException e) {
e.printStackTrace();
}
finally {
if(clientSEndpoint != null) {
clientSEndpoint.close();
System.out.println("Client closed!");
}
}
}
TABLE OF CONTENTS
- 17.1. Basic features
- 17.2. Event delivery model
- 17.3. Service Persistence
- 17.4. Client Persistence
- 17.5. Setting up the service persistence
- 17.6. Setting up the client persistence
- 17.7. Raising Replacing events
- 17.8. Handling Replacing events
- 17.9. Raising Queueing events
- 17.10. Handling Queueing events
- 17.11. Raising Private events
- 17.12. Handling Private events