CXI-Basis-Programmierreferenz / Version 2 / Datenaustausch / Ebene 2 / CxiMessageHandler /
protected: virtual long int CxiMessageHandler :: Handler2 (CxiTree& a, CxiNode& e)
Behandlungsroutine für empfangene Meldung
a:
Empfangene Meldung
e:
Zusatzinformationen zur Meldung
Um einen erweiterten Meldungssender und -empfänger zu definieren, sollte eine Ableitung der Klasse CxiMessageHandler erstellt werden, wobei die virtuelle Funktion Handler2 überschrieben wird.
Jede vollständig eingetroffene Meldung wird danach sofort als Parameter an die Funktion Handler2 übergeben und muss von ihr verarbeitet werden. Nach der Rückkehr wird die Verarbeitung als beendet betrachtet und der CXI-Baum gelöscht.
Wird die virtuelle Funktion Handler2 nicht überschrieben, werden alle ankommenden Meldungen ignoriert. Dies ist für reine Meldungssender nützlich.
Weitere Anmerkungen und Einschränkungen siehe CxiMessageHandlerBase::Handler1.
Der Parameter e ist ein CxiNode, der folgende Informationen enthält:
MsgA.Handler (Str):
= Name des Empfängers. Dieser Name entspricht meistens dem Namen, der beim Konstruktor angegeben wurde. Eine Ausnahme liegt vor, wenn das Objekt den Namen "@Default" besitzt; in diesem Fall werden alle unzustellbaren Meldungen an den Handler übergeben, die Variable MsgA.Handler enthält den Namen, an den die Meldung eigentlich gehen sollte.
MsgA.Proto (Num):
= Protokoll. Diese Variable enthält
5 (cxiMsgProtoExtended) für eine normale Meldung oder für eine Treibermeldung im DriverMode 0,
6 (cxiMsgProtoExtendedDriver) für eine Treibermeldung im DriverMode 1,
1 (cxiMsgProtoDefault) für eine automatisch konvertierte CxiNode-Meldung (PostMessageBlock).
MsgA.From (Str):
= Name des Absenders der Meldung. Wurde die Meldung mit der Memberfunktion Post verschickt, wird automatisch der Name des Absenders mit übertragen.
MsgA.Via (Lst):
= Name(n) des/der Zwischen-Handler, die die Meldung weitergeleitet haben. Werden Meldungen mit der Memberfunktion Pass verschickt, wird automatisch der Name des Zwischen-Absenders hier eingetragen. Existieren keine Zwischenstufen, ist diese Variable nicht vorhanden.
MsgA.To (Str):
= vollständiger Name des Empfängers. Diese Variable enthält die komplette Empfängerangabe einschließlich Pfadangaben.
MsgA.Unit (Str):
= erste Komponente des Namens. Bei Meldungen an Treiber steht hier der Treibername.
MsgA.Name (Str):
= lokale Komponente des Namens. Bei Meldungen an Treiber steht hier der Rest des Namens ohne den Treibernamen.
Weitere Variablen können vorhanden sein, sie werden zum Teil intern benötigt.
ACHTUNG: Bevor ein CxiMessageHandler...-Objekt gelöscht werden kann, muss der Handler verlassen werden. Programme können abstürzen, wenn sich beim Löschen des Objekts gerade eine Meldung in Bearbeitung befindet. Daher wurde mit RequestShutDown und QueryReceiverState eine Möglichkeit geschaffen, das Beenden eines Empfängers asynchron anzustoßen. Innerhalb von Destruktoren sollte WaitShutDown() aufgerufen werden. Diese Funktion wartet, bis sich keine Meldungen mehr in Verarbeitung befinden, dann deaktiviert sie den Empfänger. Erst jetzt kann das Receiver-Objekt gefahrlos gelöscht werden. Die von CXI selbst zur Verfügung gestellten Destruktoren rufen WaitShutDown() automatisch auf.
Portabilität:
Diese Funktion ist in allen unterstützten Systemen verfügbar, unter DOS müssen sich Sender und Empfänger im gleichen Programm befinden.
Weitere Memberfunktionen:
CxiMessageHandler(...) - Konstruktor
WaitState - Wartezustand
Post - Verschicken einer erweiterten Meldung
Pass - Weiterleiten einer empfangenen Meldung
SetDriverMode - Treiber für externe Meldungen
DispatchExternalMessage - Externe Meldung lokal weiterleiten
IsInHandler - Ist der Handler aktiv?
QueryReceiverState - Aktivierungsstatus
RequestShutDown - Herunterfahren eines Empfängers
Beispiel:
#include <stdio.h>
#include "cxi.h"
class TestDriver : public CxiMessageHandler
{
public:
TestDriver (const char *name)
: CxiMessageHandler (name) {}
protected:
virtual long int Handler2 (CxiTree& p, CxiNode& e);
};
long int TestDriver::Handler2 (CxiTree& p, CxiNode& e)
{
printf ("\nACTION=\"%s\"\n", p.GetItem ("ACTION", -1));
p.DumpVars (0, "Received message");
e.DumpVars (0, "Extended information");
return 0;
}
int main ()
{
CxiTreeMem a = "ACTION=TEST;DATEN=KEINE;SUB={VAR=TEST;}";
TestDriver tr = "TR";
printf ("\nStatus = <%d>\n", tr.Status ());
cxiExtendedPost (a, "TR", "(Sender1)", 0);
cxiExtendedPost (a, "TR\\Weiter\\So", "(Sender2)", 0);
return 0;
}
Ausgabe des Programms:
Status = <0>
ACTION="TEST"
***[1] 1995-10-28 20:16:28.430 *** Received message
<*Window*> <Root> \
ACTION Str "TEST"
DATEN Str "KEINE"
SUB Sub
<Node> \SUB
VAR Str "TEST"
***[2] 1995-10-28 20:16:28.430 *** Extended information
<Data>
MsgA.Handler Str "TR"
MsgA.Proto Num 5
MsgA.From Str "(Sender1)"
MsgA.To Str "TR"
MsgA.Unit Str "TR"
MsgA.Name Str ""
MsgA.Id Str ":MX3T2CE45CCAZ9HG1DP12A0"
MsgA.Type Num 4099
ACTION="TEST"
***[3] 1995-10-28 20:16:28.460 *** Received message
<*Window*> <Root> \
ACTION Str "TEST"
DATEN Str "KEINE"
SUB Sub
<Node> \SUB
VAR Str "TEST"
***[4] 1995-10-28 20:16:28.460 *** Extended information
<Data>
MsgA.Handler Str "TR"
MsgA.Proto Num 5
MsgA.From Str "(Sender2)"
MsgA.To Str "TR\Weiter\So"
MsgA.Unit Str "TR"
MsgA.Name Str "Weiter\So"
MsgA.Id Str ":MX3T1CE45CCAZ9HR2DP12A0"
MsgA.Type Num 4099
Wird der Meldungstrace aktiviert, erhält man den folgenden Inhalt der Tracedatei:
***[1] 1995-10-29 01:32:25.650 *** $$$ BEGIN DUMP $$$
<Data>
Filename Str "c:\cximsg.trc"
Ignores Str "PROTOCOL;@TRACE"
Excludes Str "@Dummy;@WaitState;OLDACTION=@WaitState"
Options Str "AIRED"
@List Lst <empty>
***[2] 1995-10-29 01:32:25.680 *** Received message
from: (Sender1)
to/unit: TR
<MsgExt>
MsgA.Handler Str "TR"
MsgA.Proto Num 5
MsgA.From Str "(Sender1)"
MsgA.To Str "TR"
MsgA.Unit Str "TR"
MsgA.Name Str ""
MsgA.Id Str ":MX3T2CE45CCEK04G1DP12A0"
MsgA.Type Num 4099
MsgA.Message Sub
<MsgRoot> \
ACTION Str "TEST"
DATEN Str "KEINE"
SUB Sub
<MsgNode> \SUB
VAR Str "TEST"
***[3] 1995-10-29 01:32:25.780 *** Received message
from: (Sender2)
to/unit: TR
name: Weiter\So
<MsgExt>
MsgA.Handler Str "TR"
MsgA.Proto Num 5
MsgA.From Str "(Sender2)"
MsgA.To Str "TR\Weiter\So"
MsgA.Unit Str "TR"
MsgA.Name Str "Weiter\So"
MsgA.Id Str ":MX3T1CE45CCEK0502DP12A0"
MsgA.Type Num 4099
MsgA.Message Sub
<MsgRoot> \
ACTION Str "TEST"
DATEN Str "KEINE"
SUB Sub
<MsgNode> \SUB
VAR Str "TEST"
***[4] 1995-10-29 01:32:25.870 *** $$$ END DUMP $$$
<Data>
FileName Str "c:\cximsg.trc"
Options Str "AIRED"
Excludes Str "@Dummy;@WaitState;OLDACTION=@WaitState;"
Ignores Str "PROTOCOL;@TRACE;"
Flags Num 2
Status Num 0
StatusName Str "ok"
@List Lst <empty>
Das genaue Format der Dump-Ausgabe ist versionsabhängig und kann daher von diesem Beispiel abweichen.