AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi neues Ereignis in TServerSocket
Thema durchsuchen
Ansicht
Themen-Optionen

neues Ereignis in TServerSocket

Offene Frage von "oki"
Ein Thema von oki · begonnen am 29. Nov 2006 · letzter Beitrag vom 1. Dez 2006
Antwort Antwort
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#1

neues Ereignis in TServerSocket

  Alt 29. Nov 2006, 19:15
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:
    property OnNewMessage : TNotifyEvent read FOnNewMessage write FOnNewMessage; Gruß oki
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#2

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 08:21
Moin,

heut jemand 'ne Idee?

Gruß oki
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#3

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 12:46
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:
property OnClientRead: TSocketNotifyEvent;
type TSocketNotifyEvent = procedure (Sender: TObject; Socket: TCustomWinSocket) of object;
Möchte man z.B. an den empfangenen Text kommen, so ruft man die ReceiveText-funktion des übergebenen Objektes Socket auf.

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:
Das Ereignis OnGetSocket tritt ein, wenn der Server-Socket ein neues TServerClientWinSocket-Objekt erstellen muß, das den Server-Endpunkt einer Verbindung zu einem Client-Socket repräsentiert.

type
TGetSocketEvent = procedure (Sender: TObject; Socket: TSocket; var ClientSocket: TServerClientWinSocket) of object;
property OnGetSocket: TGetSocketEvent;

Beschreibung

In einer Behandlungsroutine für das Ereignis OnGetSocket können Sie einen spezialisierten Nachkommen von TServerClientWinSocket für die zu verwendende Server-Socket-Komponente erzeugen. Geben Sie das neue TServerClientWinSocket-Objekt im Parameter ClientSocket zurück. Der Parameter Sender enthält das TServerWinSocket-Objekt, das den Server-Endpunkt der empfangenden Verbindung beschreibt.
Tolle sache, ich schaffe mir also meinen eigenen Nachfahren meiner ClientSocket, übergebe sie im OnGetSocket-Ereignis und kann jetzt in den TserverSocket-Ereignissen in denen Socket übergeben wird auf meine eigenen Member zugreifen.

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:
  TBaseGPRSServerClientWinSocket = class(TServerClientWinSocket)
  private
    FConnectTime: TDateTime;
    ClientID : Integer;
    ClientName : string;
...
  protected
    procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent); override;
  public
...
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.
"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
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#4

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 13:17
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.
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#5

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 13:27
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
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#6

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 13:58
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.
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#7

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 14:58
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:
procedure TMyServerSocket.GetSocket(Sender: TObject; Socket: Integer;
  var ClientSocket: TServerClientWinSocket);
begin
  ClientSocket := TGPRSReceiveServerClientWinSocket.Create(Socket, self.socket);
  Clientsocket.OnIdentify := self.OnIdentify;
  ....
end;
OnIdentify ist dann halt mal so 'n neues Ereignis.

Hmmmm.?! Klingt aber erst mal simpel.


Übrigens, wenn, dann sollen sich dort natürlich auch alle melden.

Gruß oki
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#8

Re: neues Ereignis in TServerSocket

  Alt 30. Nov 2006, 21:46
Hi,

ich hab das jetzt mal getestet.
Delphi-Quellcode:
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 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.

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
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#9

Re: neues Ereignis in TServerSocket

  Alt 1. Dez 2006, 09:15
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:
    function GetClientSocket(Socket: TSocket): TServerClientWinSocket; dynamic; Hier rufst Du aber nicht Inherited, sondern OnGetSocket, falls es assigned ist, anderenfalls criertst Du deine ClientSocketKlasse.
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.
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#10

Re: neues Ereignis in TServerSocket

  Alt 1. Dez 2006, 10:41
Zitat von Sidorion:
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.
klar, nun mach ich auch noch die Anfängerfehler.

Dank und gruß

oki
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz