• No results found

The central abstraction of the Peerlet API is the peerlet. All peerlets implement the Peerlet interface either directly, or more commonly, by extending the class

GenericPeerlet that implements the interface. The peerlet interface is defined as follows:

interface Peerlet {

/*

* the getPeerletID method returns the id of this peerlet

*/

public PeerletID getPeerletID ();

/*

* the getProtocolID method returns the protocol supported by this peerlet

*/

public ProtocolID getProtocolID (); /*

* the init method initializes the Peerlet and puts it into service

*/

public void init (); /*

* the destroy method is called just before unloads the Peerlet.

*/

public void destroy (); /*

* the handleProemEvent method gets called when a system event occurs.

*

*/

public void handleEvent(proem.Event event); }

All methods defined in the Peerlet interface are called by the Peerlet engine at various stages of the peerlet’s lifecycle. They are called in the following sequence:

1. getProtocolID: The peerlet engine constructs the peerlet and calls the getProtocolID methods to determine which protocol this peerlet implements5. If the peerlet engine already hosts a peerlet that implements the same protocol, the start-up process is terminated.

2. init: The calling of this method signals to the peerlet that it has entered an active state. This allows the peerlet to initialize data structures.

3. handleProemEvent: this method signals an event that should be handled by the peerlet. The method is called exactly once for each event occurrence. Calls to this method may occur concurrently and it is the responsibility of the programmer to make sure that the code is reentrant.

4. destroy: this method signals that the peerlet instance is about to be destroyed. It enables the peerlet to release resources and save persistent state information.

VI.2.1Event Handling

Peerlets receive and react to events generated by the Peerlet engine. The Peerlet Framework defines three event types (Figure 23):

1. Communication events: events of this type indicate a message from a remote

peer

2. Discovery events: events of this type indicate that a new peer has been

discovered or that a previously encountered peer has disappeared 3. User interface events: events of this type indicate input from the user

Each event type is represented by a Java interface.

5 All ID classes (PeerletID, ProtocolID, UserID, …) are simple wrapper classes that encapsulate a Java

Figure 23. Proem event type hierarchy The IncomingMessageEvent Interface

An event of type IncomingMessageEvent is fired whenever the peerlet engine receives a message that belongs to the same protocol as supported by the peerlet. The event encapsulates the incoming messages which can be extracted using the getMessage

method (the structure of messages and the mechanisms for sending messages are discussed in Chapter VI.5.3).

public interface IncomingMessageEvent extends proem.Event {

public proem.Message getMessage(); }

The UserInterfaceEvent Interface

An event of type UserInterfaceEvent is fired whenever there is new input from the user. The event encapsulates a message object which can be extracted using the

public class UserInterfaceEvent implements proem.Event {

public proem.Message getMessage() }

The BeginEncounterEvent Interface

An event of type BeginEncounterEvent is fired whenever a new peer has been discovered in the vicinity that supports the same peerlet protocol. The event encapsulates an object of class Encounter which can be extracted using the getEncounter

method. An encounter object contains information about the peer and user encountered when the encounter happened (encounter objects are discussed in Chapter VI.5.4)

public interface BeginEncounterEvent extends proem.Event {

public proem.Encounter getEncounter() }

The EndEncounterEvent Interface

An event of type EndEncounterEvent is fired whenever a previously encountered peer disappears i.e. is no longer visible. The event encapsulates an object of class

Encounter which can be extracted using the getEncounter method.

public class EndEncounterEvent implements proem.Event {

public proem.Encounter getEncounter() }

VI.2.2Example

The following code segment illustrates the basic structure of event handling code in a peerlet.

public void handleEvent(proem.Event event) {

if (event instanceof BeginEncounterEvent) {

Encounter encounter = ((BeginEncounterEvent)event).getEncounter(); UserProfile profile = encounter.getProfile();

UserID user = profile.getUserID(); // action 1

}

else if (event instanceof EndEncounterEvent) {

Encounter encounter = ((BeginEncounterEvent)event).getEncounter(); UserProfile profile = encounter.getProfile();

UserID user = profile.getUserID(); // action 2

}

else if (event instanceof IncomingMessageEvent) { Message in = ((IncomingMessageEvent).event).getMessage(); if (in.getBody() instanceof A) { //action 3 }

else if (in.getBody() instanceof B)

{

//action 4

}

}

else if (event instanceof UserInterfaceEvent) { Message in = ((UserInterfaceEvent).event).getMessage(); if (in.getBody() instanceof C) { //action 5 }

else if (in.getBody() instanceof D)

{

//action 6

}

} }

The handleProemEvent consists of a sequence of if-then-else statements differentiating between four cases. If the event indicates an encounter (BeginEncounterEvent), the peerlet extracts the encounter object encapsulated in the event; it then extracts the user’s profile from the encounter and the user’s id from the

event indicates the end of an encounter (EndEncounterEvent) instead of the beginning. Of course, the actions performed are different (action 2).

If the event indicates a message (IncomingMessageEvent), the peerlet first extracts the message object from the event and may then, depending on the type of the message, perform any number of actions (action3 and 4). User interactions are handled in exactly the same way as messages received from remote peers (UserInterfaceEvent). All user input is represented and send to a peerlet in form of a message which can be extracted from the event object. The message type, which indicates the nature of the user input, can be used to decide which action should be performed (action 5 and 6).