|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.ObjectAMETAS.event.AMETASEventHandler
AMETAS.servicedev.AMETASServiceProxy
AMETAS.servicedev.AMETASSyncServiceProxy
Diese Klasse implementiert einen klassischen Proxy für die Nutzung
eines AMETAS-Dienstes. Das Problem bei der Dienstnutzung ist der
relativ umständliche Umgang mit Dienstaufrufen. Diese Aufruf
müssen natürlich über Agentennachrichten erfolgen. D.h. der Klient
muß sich zuerst die ID des Dienstes vom Dienstvermittler der
Stelle besorgen, dann muß er geeignete Nachrichten basteln, sie im
PostOffice ablegen und auf die Antwort warten. Dieser Ganze
Vorgang kann zurecht als etwas umständlich, unintuitiv und
fehleranfällig bezeichnet werden. Zudem muß jeder Klient diese
Schritte selbst implementieren, so daß große Teile des Codes jedes
Klienten für die Bearbeitung von Dienstaufrufen zuständig sind,
obwohl diese Schritte für alle Klienten gleich
aussehen. Wünschenswert wäre die Möglichkeit, einen Dienst so
nutzen zu können, als sei er ein lokales Objekt, auf dem man
einfach eine Methode aufruft. Hier kommt der Proxy ins Spiel. Er
kapselt die Details eines Dienstaufrufes über Agentennachrichten
weitgehend und verbirgt die Aufrufe hinter Methoden. Der Klient
ruft also eine Methode auf dem Proxy auf, welche die
Aufrufparameter geeignet verpackt, eine Nachricht generiert, diese
an den Dienst schickt, auf die Antwort wartet, diese entpackt und
die entsprechenden Daten dem Aufrufer zurückgibt. Jeder
AMETASSyncServiceProxy besitzt eine bestimmte
Basisfunktionalität, welche von dieser Basisklasse implementiert
wird. Die dienstspezifischen Funktionen müssen in entsprechenden
Subklassen zu dem speziellen Dienst implementiert werden. Am
einfachsten ist dies, wenn der Dienstentwickler den Proxy gleich
mitliefert. Dieser kann ein Agent instantiieren und verwenden.
Achtung : Ein AMETASServiceProxy ist nicht
Thread-Safe! Aufrufe auf dem Proxy sind also immer von
Stellennutzer-Thread (Treiber-Thread) zu machen. Jeder
Stellennutzer besitzt neben seinem eigentlichen Thread, dem
Treiber-Thread, noch einen zweiten, einen
AMETASEventNotificator. Dieser dient zur
Benachrichtigung des Stellennutzers über das Auftreten von
Ereignissen. Dieser Thread ruft, falls der Stellennutzer
entsprechend als EventListener registriert ist, eine
handle-Methode auf, die der Stellennutzer
bereitstellen muß (siehe AMETAS-Tutorial für weitere
Informationen). Theoretisch könnte innerhalb dieser
handle-Methode ebenfalls ein Aufruf auf dem
Proxy-Objekt gemacht werden. Dies könnte dazu führen, daß beide
Threads gleichzeitig eine Methode aufrufen. In diesem Fall liefern
beide Aufrufe undefinierte Ergebnisse zurück! Dies gilt auch,
wenn beide gleichzeitig unterschiedliche Dienstmethoden des
Proxies aufrufen! Wenn eine Dienstmethode als Reaktion auf ein
Ereignis aufgerufen werden soll, so sollte in der
handle-Methode der Treiber-Thread informiert werden
(z.B. über Member-Variablen des Stellennutzers) und daraufhin
selbst aktiv werden. Davon abgesehen ist es sowieso fragwürdig,
langwierige Aktonen direkt in einer handle-Methode
auszuführen. Durch diese wird nämlich der
AMETASEventNotificator blockiert! Dies führt dazu,
daß weitere Ereignisse nicht zugestellt werden können. Wenn ein
Stellennutzer also in einer handle-Methode z.B. eine
Endlosschleife startet, dann wird er nie wieder Ereignisse
bekommen! Also: handle-Methode immer so kurz wie
möglich fassen!
AMETASSyncServiceProxy, die vom Proxy-Entwickler zu
implementieren ist, macht generell folgendes:
setTimeout(long) eingestellt werden kann.ProxyTimeoutException
zurück.
Damit der Proxy die Nachricht, in der die Dienstantwort steckt,
empfangen kann, ist er als AMETASEventHandler
implementiert. Der Stellennutzer instantiiert den Proxy und
initialisiert ihn über init. In init
werden alle Aktionen durchgeführt, die nötig sind, damit der Proxy
die Antwortnachrichten des Dienstes erhält. Hierzu muß der Agent
ein AMETASNotifiableAgent (oder, wenn der Proxy von
einer Benutzeradapter verwendet wird, ein
AMETASNotifiableUserAdapter) sein. Der Proxy erhält
daraufhin, in seiner Eigenschaft als EventHandler alle Nachrichten
von dem anzusprechenden Dienst.
| Field Summary | |
protected long |
m_lTimeout
Die Zeit in Millisekunden, nach der ein Aufruf als gescheitert gilt, falls keine Antwort gekommen ist. |
protected AMETASMessageID |
m_midRequestID
Hier wird die Nachrichten-ID der Anfragenachricht vor dem Absenden abgelegt. |
| Fields inherited from class AMETAS.servicedev.AMETASServiceProxy |
m_aobjResponseBody, m_drvClientDriver, m_idService, m_mesResponse, m_puClient, m_puidClientID, m_sResponseTypeSpec, m_sServiceName, NO_SERVICE_NAME, OK, SERVICE_NOT_FOUND |
| Constructor Summary | |
AMETASSyncServiceProxy(AMETASPlaceUser puClient,
AMETASPlaceUserDriverIf drvClientDriver)
Konstruktor. |
|
| Method Summary | |
protected void |
depositRequestAndWait(java.lang.Object[] aobjParams)
Legt eine Anfragenachricht ab. |
boolean |
handleServiceMessage(java.lang.String sTypeSpec,
java.lang.Object[] aobjBody,
AMETASMessage mes)
Empfängt die Antworten des Dienstes. |
void |
setTimeout(long lTimeout)
Setzt das Timeout, das beim Dienstaufruf eingehalten werden soll. |
| Methods inherited from class AMETAS.servicedev.AMETASServiceProxy |
cleanup, depositRequest, getServiceID, getServiceName, init, init, output, setServiceName |
| Methods inherited from class AMETAS.event.AMETASEventHandler |
handleApplicationMessage, handleCustomMessage, handleMessageEvent, handleMessageMessage, handlePlaceEvent, handlePlaceMessage, handlePlaceUserEvent, handleSecurityMessage, handleTradingMessage |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
protected long m_lTimeout
ProxyTimeoutException.
protected transient AMETASMessageID m_midRequestID
ReplyTo-Feld einer Antwortnachricht verglichen
werden. So kann sichergestellt werden, daß die erhaltene
Antwort auch eine Antwort auf die abgesendete Anfrage ist.
| Constructor Detail |
public AMETASSyncServiceProxy(AMETASPlaceUser puClient,
AMETASPlaceUserDriverIf drvClientDriver)
puClient - Das Stellennutzerobjekt des Klienten, zu
übergeben als thisdrvClientDriver - Der Treiber des Klienten| Method Detail |
public void setTimeout(long lTimeout)
lTimeout - Timeout in Millisekunden.
protected void depositRequestAndWait(java.lang.Object[] aobjParams)
throws ProxyTimeoutException
aobjParams - Die Nutzlast der Anfragenachricht.
ProxyTimeoutException - falls ein Timeout auftritt
bevor die Antwort des Dienstes eingetroffen ist.
public boolean handleServiceMessage(java.lang.String sTypeSpec,
java.lang.Object[] aobjBody,
AMETASMessage mes)
m_mesResponse abgelegt, bevor der
Treiber-Thread aufgeweckt wird. vctBodyData wurde
bereits von der ersten Typspezifikation (REQUEST) befreit.
handleServiceMessage in interface AMETASEventHandlerIfhandleServiceMessage in class AMETASEventHandlersTypeSpec - Die Typspezifikation der AntwortnachrichtaobjBody - Die Nutzlast der Antwortnachrichtmes - Die Antwortnachricht selbst
true, falls die eingehende Nachricht von
dieser Methode verarbeitet wurde, false sonstAMETASMessage
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||