Autor |
Beitrag |
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 15.09.11 23:30
Moin!
Daniel775 hat folgendes geschrieben : | Da wird es hapern. Ich hab mir die .add Procedure mal angesehen. Ich kann da kein Objekt übergeben, oder? Wie kann ich da ansetzen? |
Der "Witz" an dem TCmdSeq-Objekt ist ja, dass es keine strukturierten Daten annimmt, sondern immer nur einfache Datentypen. Kennst du die Methode und das Konzept von TPersistent.Assign() und .AssignTo()? Hier ist das genau so: in der Methode, die das Objekt übergeben soll gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt. Das ist die einzige Möglichkeit bei einer Änderung des Objekts keinen Datenmatsch zu produzieren. Ändert sich das Objekt, muss auch ein entsprechend geändertes Transport-Verfahren benutzt werden (hier: ein anderes Token).
Alternative wäre die Delphi-eigene Methode zum De-/Serialisieren von Objekte, so wie es die VCL/IDE mit den Komponenten tut. Ist aber bischen frickelig.
Noch ein anderer Ansatz ist die Transformation in das INI-Format, dieses als Text transportieren und auf der anderen Seite wieder aus dem INI-Format lesen.
Du merkst schon, egal was man macht, wenn man einfach nur "auf der einen Seite rein und auf der anderen genau so wieder raus" haben will, geht das gar nicht so einfach... jedenfalls nicht, wenn es "sauber" sein soll.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Daniel775
Hält's aus hier
Beiträge: 5
|
Verfasst: Fr 16.09.11 13:38
Zitat: | ...gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt. |
Das heisst Praktisch für jede Eigenschaft in meinem Objekt ein neues Token und wenn sich die Eigenschaft oder das Objekt verändert diesse Änderung wieder über die Methode an das TCmdSeq-Objekt schicken. Hab ich das richtig verstanden?
Ich mache das im Moment mit einer .ini Datei. Und suche jetzt eine Client <> Server Lösung. Das würde bedeuten, das auch das Terminatorzeichen Protokoll für diese Aufgabe völlig ausreichend wäre!?
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 16.09.11 13:59
Moin!
Daniel775 hat folgendes geschrieben : | Zitat: | ...gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt. | Das heisst Praktisch für jede Eigenschaft in meinem Objekt ein neues Token und wenn sich die Eigenschaft oder das Objekt verändert diesse Änderung wieder über die Methode an das TCmdSeq-Objekt schicken. Hab ich das richtig verstanden? |
Ähm, nein. Machen wir mal ein Beispiel:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| type TSettings = class(TObject) private FStr: String; FInt: Integer; public function AsCmdSeq: TCmdSeq; property Str: String read FStr write FStr; property Int: Integer read FInt write FInt; end;
TForm1 = class(TForm) NBFPAClient1: TNBFPAClient; NBFPAServer1: TNBFPAServer; Button1: TButton; procedure Button1Click(Sender: TObject); procedure NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter); public Settings: TSettings; end;
implementation
function TSettings.AsCmdSeq: TCmdSeq; begin Result := TCmdSeq.Create(123); Result.Add(FStr); Result.Add(FInt); end;
procedure TForm1.Button1Click(Sender: TObject); begin NBFPAClient1.SendAndFree(Settings.AsCmdSeq); end;
procedure TForm1.NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter); begin case PA.CurrentToken of 123: begin Settings.Str := PA.Inbound.Strings[1]; Settings.Int := PA.Inbound.AsInt[2]; end; 122: begin Settings.Str := PA.Inbound.Strings[1]; end; end; end; |
Daniel775 hat folgendes geschrieben : | Ich mache das im Moment mit einer .ini Datei. Und suche jetzt eine Client <> Server Lösung. Das würde bedeuten, das auch das Terminatorzeichen Protokoll für diese Aufgabe völlig ausreichend wäre!? |
Jedes Protokoll ist für die Übertragung geeignet, egal welches. Damit wird ja nur Transportiert. Wie du die Einstellungen verwaltest, also als Objekt, Record, INI-Text, etc. ist doch davon unabhängig.
Um die Frage zu beantworten: ja, das Terminatorzeichen-Protokoll wäre dafür auch ausreichend.
Machen wir das mal anders: was soll das denn werden und worauf legst du Wert bei der Sache?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Für diesen Beitrag haben gedankt: Daniel775
|
|
Daniel775
Hält's aus hier
Beiträge: 5
|
Verfasst: Fr 16.09.11 20:20
Zitat: |
Machen wir das mal anders: was soll das denn werden und worauf legst du Wert bei der Sache?
|
Mein aktuelles Projekt ist eine Datenbankgestützte Zeiterfassung. Oder einfach gesagt, eine Stempeluhr. Mit Mitarbeiter, Urlaubs -und Fehlzeitenverwaltung. Es gibt ein UserFront-End als eigenständiges Programm wo halt eingestempelt wird und ein Admintool. Das Admintool möchte ich halt mit gewissen Funktionen ausstatten.
Wartungsmodus ein/aus, Anzeigedauer der letzten Einstempelungen usw.
Diese möchte ich mittels Client/Serververbindung an die Stempeluhr schicken. In Form einer Datei die dann beim start immer eingelesen wird. Dein Beispiel wird mir sehr helfen das umzusetzen .... vielen lieben Dank.
Das mit den Versionen in der ClientExecute Procedure gefällt mir und ist ein sehr guter Tipp.
Grüße
|
|
Martok
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Di 06.03.12 00:13
Hallo,
ich baue momentan ein RPC-Interface rund um NBFPA. Das ganze läuft so ab, dass man dann z.B. ein OnEntityCall-Event bekommt, mit den Parametern: (Connection, EntityRef, Function, Parameter). Die kann man dann in Anwendungs-Code weiterverteilen an die richtigen Handler.
Das Problem ist jetzt, die Parameter richtig zu zerpflücken. Wenn ich einfach nur die TInboundFrameList übergebe, ist das unhandlich, da ja die ersten paar Argumente "intern" sind: Entity,FunctionCode etc.
Einfach die verarbeiteten ArgumentFrames aus der Liste löschen (damit die Paremter vorwandern) geht nicht, das kollidiert mit der NBFPA-Internen Verarbeitung. Ich würde die also gerne vorher zerpflücken und eventuell in ein Array of Const oder Variant reinschieben. Das ist an sich auch okay, aber die Überdeckung der damit darstellbaren Datentypen zu den mit NBFPA übertragbaren Formate ist gelinde gesagt gering. Selbst mit Auto-Konvertierung (Datentypen kann man ja mitsenden) wird das entweder nicht einfach oder bandbreitentechnisch eher schlecht.
Hat mit sowas jemand Erfahrung? Ich bin auch für Alternativkonzepte immer offen. Alles, was im Endeffekt einfach zu verwenden ist.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 07.03.12 00:54
Moin!
An einem Stück Dispatcher-Code im OnExecute oder einer auf´s Nötige reduzierten Kopie der Parameter aus der InboundFrameList wird wohl irgendwie kein Weg vorbeiführen...
Aber, ehrlich gesagt, mir ist sowieso schleierhaft, wie du den Methoden-Call (abstrahiert) "durchreichen" willst. Das geht doch immer nur für bekannte Methoden, oder klemmt mir da wieder ein Synapse?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 07.03.12 01:04
*Mit Zaun wedel* array of const AKA array of TVarRec
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Martok
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mi 07.03.12 01:16
Hallo, danke für die Antwort.
Ja, Dispatcherkrams ist da. Geht nur noch darum wie die aussehen soll
Kurzfassung: es gibt z.B. auf dem Client eine Funktion:
EntityCall(EntityID: Cardinal; Function: Word; Params: ????).
Die baut daraus eine TCmdSeq mit PacketID ENTITY_CALL und den Argumenten EntityID, Function, Param1, Param2, ..., ParamN
Auf dem Server wird im OnExecute das zerpflückt und ein OnEntityCall(Entity, Func, ???) aufgerufen.
Dort bindet der User seinen Dispatcher zu den Entities an und diese wiederum machen dann je nach Function-Code was.
Die Parameter kann man als array of const reinschieben und auf der anderen Seite wieder so parsen. Das geht, Problem ist, dass da nur eine kleine Auswahl von Datentypen möglich ist. Byte/Word/Cardinal/Integer ist da alles eins. Variant wäre weniger problematisch, aber es passt immer noch nicht alles (Extended fehlt und ByteArrays z.B. sind sehr seltsam).
Ich hab schon überlegt, Parameterobjekte zu nehmen, die sich selbst serialisieren. Ohne anonyme Klassen (Hallo, Java) bedeutet das aber, dass haufenweise Klassen zu deklarieren und zu implementieren sind. Ich will ja grade sowas vereinfachen, nicht eine "Menge Code" durch eine andere "Menge Code" erledigen.
Wenn Delphi assoziative Arrays mit TypInfo hätte... *träum*
BenBE hat folgendes geschrieben : | Mit Zaunpfahl wedel* array of const AKA array of TVarRec |
Lesen. Hirn anschalten. Nochmal lesen. Dann vielleicht posten.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 11.03.12 03:33
Moin!
Jaa, nach intensivem Überlegen würde ich zu einer (weiteren, nur für die Weiterverarbeitung benötigten) TInboundFrameList als Parameter-Konvention raten, eben genau so, wie es auch reinkommt, datentypenfrei. Das hat zwar den doofen "Nachteil", dass du dann die Parameter jedes mal kopieren musst, das sollte aber nicht so schlimm sein, da die Strings auf dem Heap ja referenzgezählt sind und nicht dupliziert werden sollten. Damit "überlässt" du ja quasi der Zielmethode die Wahl, was das für Parameter und wie sie handzuhaben sind. Sobald du das typensicher haben willst, wird das mit Delphi wohl nicht so lustig werden...
Also kurz: OnEntityCall(Entity, Func, Params: TInboundFrameList)
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
|