![]() |
neues Ereignis in TServerSocket
Hi Leute,
im Moment hab ich echt ne'n Irrläufer. Ich versuche folgendes: Ich habe eine vererbte Klasse von TServerClientWinSocket geschrieben, welche mir die empfangenen Daten vor verarbeitet. Diese neue Klasse übergebe ich im Ereignis OnGetSocket der TserverSocket-Kompo. Das klappt soweit alles bestens. Nun will ich aber meiner vererbten TServerClientWinSocket neue Ereignisse implementieren, welche dann in einer neuen TServerSocket-Kompo zur Verfügung stehen sollen. Wenn ich mir anschaue wie die OnRead etc. Ereignisse implementiert sind, verrenne ich mich immer. Offensichtlich sehe ich den Wald voller Bäume nicht. Kann mal einer so nett sein und mir kurz einen Plan geben wo ich was implementieren muß, damit meine neuen Ereignisse durchgereicht werden? Ich würde es mal ganz einfach mit folgendem probieren:
Delphi-Quellcode:
Gruß oki
property OnNewMessage : TNotifyEvent read FOnNewMessage write FOnNewMessage;
|
Re: neues Ereignis in TServerSocket
Moin,
heut jemand 'ne Idee? Gruß oki |
Re: neues Ereignis in TServerSocket
Ich glaube, ich muß mein Problem noch mal etwas anschaulicher formulieren.
wenn man eine TServerSocket-Kompo auf seinem Formular platziert, dann kann man über diverse Ereignisse Informationen über die Aktivitäten der verbundenen Clients erhalten. Als Beispiel sei hier das Ereignis OnClientRead genannt. dieses ist wie folgt deklariert:
Delphi-Quellcode:
Möchte man z.B. an den empfangenen Text kommen, so ruft man die ReceiveText-funktion des übergebenen Objektes Socket auf.
property OnClientRead: TSocketNotifyEvent;
type TSocketNotifyEvent = procedure (Sender: TObject; Socket: TCustomWinSocket) of object; diese instanz von Socket "lebt" so lange, wie der Client Connected ist. Das heißt also, das das Handle der socket beim nächten OnClientRead-Ereignis das selbe ist. Logisch! Da ich einen spezialisierten Nachfahren von TServerSocket (implizit auch der ClientSockets) haben möchte, leite ich hier erst mal meine eigenen Klassen ab. irgentwo muß man ja anfangen, also nehme ich mir als erstes die Clients vor. Das erscheint auch recht einfach, da die OH zum Ereignis OnGetSocket der Kompo TServerSocket folgendes sagt: Zitat:
Warum mache ich das? aus folgendem Grund. Meine Clients senden nach einem Connect spezielle Infos, mit denen sie identifiziert werden können. Der Einfachheit halber lege ich welche fest:
Delphi-Quellcode:
Für mich entsteht dabei folgender Vorteil. Connected sich ein neuer Client, so übergebe ich im OnGetSocket-Ereignis eine neue Instanz meiner speziellen TBaseGPRSServerClientWinSocket. Bekomme ich im ersten Read die Anmeldeinfos, so trage ich die entsprechenden Werte bei den Membern ein. Also empfangenen Wert nach ID und Name durchsuchen und in FClientID und FClientName merken. Die erfolgt dann aber nicht im OnClientRead-Ereignis der TServerSocket, sondern im überschriebenen Event der TBaseGPRSServerClientWinSocket.
TBaseGPRSServerClientWinSocket = class(TServerClientWinSocket)
private FConnectTime: TDateTime; ClientID : Integer; ClientName : string; ... protected procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent); override; public ... "Oben" merkt somit keiner, das sich der Client identifiziert hat, was so auch gewollt ist. Jedes weitere Empfangen von Text kann jetzt zusätzlich mit den Ident-infos meiner ClientSocket vervollständigt werden ohne sie jedes mal neu zu senden. Kurz und knapp heißt das also, wenn meine ServerSocket eh schon eine Liste aller verbundenen Clients führt (repräsentiert durch die TBaseGPRSServerClientWinSocket), dann merke ich mir alles notwendige direkt da. Ja, die Idee fand ich gut; und klappen tut's auch. wie ihr bereits mitbekommen habt, geht es mir um die Decodierung spezieller Sequenzen meiner sendenden Clients. Hier hab ich jetzt min. 2 unterschiedliche Gruppen von Meldungen, Befehlsfolgen und allg. Textnachrichten. Parallel möchte ich auch noch den empfangenen Text im Urzustand liefern. Nichts liegt näher, als hierfür spezielle Ereignisse vorzusehen. Diese sollen dann nach der Decodierung aufgerufen werden. Als einfaches Beispiel im Zusammenhang zu meinen Ausführungen könnte man nach dem Empfang der Identifizierungsdaten ein Ereignis OnClientIdentify einfügen. Und jetzt die alles entscheidende Frage: Wie mach ich das so, das ein neuer Nachfahre einer TserverSocket-Kompo dieses ereignis auch empfängt? Tja, da waren sie wieder, meine Probleme. Gruß oki |
Re: neues Ereignis in TServerSocket
0. Du Deklariert einen neuen Eventtyp TMyNewEvent=Procedure(Parm1 TParam1; param2; TParam2; usw: Tusw) of Object;
1. Du machst Dir einen Member von deinem neuen Eventtyp, in dem Du den Handler für den Event speicherst (FOnMyNewEvent: TMyNewEvent) 2. Du deklarierst eine neue Property mit deinem neuen Eventtyp, mit der man von aussen den Handler setzt (Property OnMyNewEvent: TMyNewEvent read FOnMyNewEvent write FOnMyNewEvent) 3. im Constructor setzt Du den Member auf nil (initialisierung) --jetzt kommt der Aufruf 4. Wenn die Formatierung abgeschlossen ist, prüfst du, ob der Member asssigned ist(dann klebt ein Handler dran) und wenn ja, rufst Du den handler auf mit z.B.: FOnMyNewEvent(Parm1, param2, usw); Du kannst quasi in diesem Fall die gespeicherte Variable als Funktion nutzen. |
Re: neues Ereignis in TServerSocket
Hi Sidorion,
dank für deine Mühe. Mein Problem ist aber nicht wie man ein Ereignis erstellt, sonder wie ich das speziell in den Socket's einarbeite. welche "Wege" muß mein Ereignis nehmen um zum Schluß bei meiner TServerSocket anzukommen? Muß ich das Ereignis auch in TServerWinSocket etablieren? Wie ersetze ich die dann in TServerSocket? Fragen über Fragen. gruß oki |
Re: neues Ereignis in TServerSocket
TServerSocket überschreiben und zwar die Methode, die OnGetSocket ruft.
Nach dem Aufruf von Inherited sollte dann Dein ServerSocket den neuen Clientsocket kennen (z.B.: der letzte in der Liste) Den kannst Du dann auf Deinen typ casten und einen handler für den neuen Event zuweisen. In diesem Handler kommt dann der neue Event an und Du kannst ihn dann weiterverarbeiten. |
Re: neues Ereignis in TServerSocket
Jo Man,
da bin ich ja noch gar nicht drauf gekommen. hört sich irgentwie brutal nach direktem Weg an. Die Standardsockets nehmen aber den Umweg über TServerWinSocket. Codemäßig meinst du das so?
Delphi-Quellcode:
OnIdentify ist dann halt mal so 'n neues Ereignis.
procedure TMyServerSocket.GetSocket(Sender: TObject; Socket: Integer;
var ClientSocket: TServerClientWinSocket); begin ClientSocket := TGPRSReceiveServerClientWinSocket.Create(Socket, self.socket); Clientsocket.OnIdentify := self.OnIdentify; .... end; Hmmmm.?! Klingt aber erst mal simpel. Übrigens, wenn, dann sollen sich dort natürlich auch alle melden. Gruß oki |
Re: neues Ereignis in TServerSocket
Hi,
ich hab das jetzt mal getestet.
Delphi-Quellcode:
Wie gesagt, es funzt erst mal. Eine saubere Methode ist das aber nicht. Das Ereignis OnGetSocket ist im published-Teil immer noch enthalten und kann somit bei Aufruf überschrieben werden. Damit werden dann alle speziellen Ereignisse unwirksam.
TGPRSServerSocket = class(TServerSocket)
private FOnLogText: TLogTextEvent; FOnClientIdentify: TClientIdentifyEvent; protected procedure LogText(Socket : TBaseGPRSServerClientWinSocket; Msg : String); procedure ClientIdentify(Sender : TObject; Socket : TGPRSReceiveServerClientWinSocket); procedure GetSocket(Sender: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); public constructor Create(AOwner: TComponent); override; published property OnClientIdentify : TClientIdentifyEvent read FOnClientIdentify write FOnClientIdentify; property OnLogText : TLogTextEvent read FOnLogText write FOnLogText; end; .... constructor TGPRSServerSocket.Create(AOwner: TComponent); begin inherited create(AOwner); // Ereignisse zuweisen self.OnGetSocket := self.GetSocket; end; procedure TGPRSServerSocket.GetSocket(Sender: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); begin ClientSocket := TGPRSReceiveServerClientWinSocket.Create(Socket, self.socket); (ClientSocket as TGPRSReceiveServerClientWinSocket).OnLogText := self.LogText; (ClientSocket as TGPRSReceiveServerClientWinSocket).OnClientIdentify := self.ClientIdentify; end; Wie gesagt, es muß noch einen anderen Weg geben. Ich glaube folgender Weg müßte gehen: TGPRSReceiveServerClientWinSocket wie gehabt nur von TCustomWinSocket ableiten. Den für TServerClientWinSocket definierten Construktor übernehmen und als Member eine eigene TServerWinSocket mit den neuen Ereignissen implementieren. Dann eine eigene TServerSocket (bei mir TGPRSServerSocket) jetzt von TCustomSocket ableiten. Hm, ich glaub, so müßte es klappen. Vielleicht kann mal jemand sagen ob ich auf dem richtigen Weg bin. Gruß oki |
Re: neues Ereignis in TServerSocket
So wie Dus gemacht hqast, wars nicht gemeint. Du musst in der Klasse TServerSocket mal nach der Methode suchen, die OnGetSocket aufruft. Diese musst Du überschreiben, nicht einfach einen handler an OnGetSocket zuweisen.
Die Events sind grundsätzlich für ausserhalb gedacht. Wenn Du Funktionalitäten ändern willst, musst Du Methoden überschreiben. In Deinem Fall:
Delphi-Quellcode:
Hier rufst Du aber nicht Inherited, sondern OnGetSocket, falls es assigned ist, anderenfalls criertst Du deine ClientSocketKlasse.
function GetClientSocket(Socket: TSocket): TServerClientWinSocket; dynamic;
Danach prüfst Du, ob der Socket vom Typ deiner ClientKlasse ist, und wenn ja, weist Du den Event zu. Guck einfach mal in den Code von TServerWinSocket. |
Re: neues Ereignis in TServerSocket
Zitat:
Dank und gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz