![]() |
Grundsatz Fragen Client/Server Anw. via Indy10
Ich beschäftige mich grade mit dem Thema Client-Server Anwendung mit den Komponenten (IdTCPServer, IdTCPClient) aus der
Indy Sammlung von Delphi 2007 Prof. Ich habe einen Server und einen Client erstellt, am Server können sich ein oder mehre Clients "anmelden" Die Clients können auch einfache Text nachrichten Verschicken, soweit kein Problem. Server:
Delphi-Quellcode:
unit uSrvMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, StdCtrls, IdContext, DateUtils, Buttons; type tClient = record Host : String; Port : Integer; end; type TForm1 = class(TForm) Memo1: TMemo; edtCommand: TEdit; Label1: TLabel; btnSend: TButton; IdTCPServer: TIdTCPServer; ltbClients: TListBox; Label2: TLabel; ComboBox1: TComboBox; Label3: TLabel; procedure IdTCPServerConnect(AContext: TIdContext); procedure IdTCPServerDisconnect(AContext: TIdContext); procedure IdTCPServerExecute(AContext: TIdContext); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin //init IdTCPServer.Active := False; IdTCPServer.Bindings.Clear; //Einstellungen IdTCPServer.DefaultPort := 666; try IdTCPServer.Active := True; except Raise; end; Caption := 'Server - Online'; end; procedure TForm1.IdTCPServerConnect(AContext: TIdContext); begin Memo1.Lines.Add('Connect: '+AContext.Binding.PeerIP); end; procedure TForm1.IdTCPServerDisconnect(AContext: TIdContext); begin Memo1.Lines.Add('Disconnect: '+AContext.Binding.PeerIP); end; procedure TForm1.IdTCPServerExecute(AContext: TIdContext); begin Memo1.Lines.Add('Message: '+AContext.Connection.IOHandler.ReadLn); end; end. Client:
Delphi-Quellcode:
unit uClMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls; type TForm2 = class(TForm) btnConnect: TButton; btnDisconnect: TButton; IdTCPClient: TIdTCPClient; Label1: TLabel; edtCommand: TEdit; btnSend: TButton; Memo1: TMemo; Label2: TLabel; procedure FormCreate(Sender: TObject); procedure btnConnectClick(Sender: TObject); procedure btnDisconnectClick(Sender: TObject); procedure btnSendClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.btnConnectClick(Sender: TObject); begin IdTCPClient.Host := 'localhost'; IdTCPClient.Port := 666; IdTCPClient.ConnectTimeout := 5000; try IdTCPClient.Connect; Caption := 'Client - Online!'; except Raise; end; end; procedure TForm2.btnDisconnectClick(Sender: TObject); begin if IdTCPClient.Connected then IdTCPClient.Disconnect; end; procedure TForm2.btnSendClick(Sender: TObject); begin if IdTCPClient.Connected then begin IdTCPClient.IOHandler.WriteLn(edtCommand.Text); end;{if} end; procedure TForm2.FormCreate(Sender: TObject); begin Caption := 'Client - Offline'; end; end. Jetzt zu den Grundsätzlichen Fragen, ich habe schon das Forum durchstöbert aber irgendwie bin ich noch nicht auf die richtigen Einträge (Tutorial) gestoßen bzw. ich kapier das irgendwie noch nicht so ganz alles. Was soll das Ganze, der Server soll wissen welche Clients Angemeldet sind um ggf. ohne Aufforderung des Clients Nachrichten an einen oder mehre Clients zuschicken, dazu muß er wissen welcher Client wie verbunden ist. Ich habe irgendwelche Ansätze gefunden die auf "TIdContext" basieren so ganz verstehen tu ich das noch nicht. Frage 1: Die Verwaltung von mehren Clients an einem Server. Das nächste Thema ist die Kommunikation zwischen Client und Server, auch zu dem Thema habe ich einiges gefunden. Das man sich ein "Protokoll" ausdenken sollte nach welchem sich die Anwendungen "unterhalten". Was ja bei einer einfachen Anwendung wie z.B. einem Chat sicherlich nicht das Problem sein sollte. Da ich jedoch plane dem Server eine Verbindung zu einer mySQL Datenbank zuverpassen meine Frage macht es da noch sinn alles per "String" zu regeln. Man könnte vom Client den Befehl schicken "Zeige mir alle Kunden" darauf hin, erstellt der Server eine SQL Abfrage und schickt dann ja was, einen riesigen zusammenhängenden String zurück, den der Client mühselig wieder in ein Array umsetzten muß um diesen anzeigen zu können. Oder kann man irgendwie ein Object bzw. Record übertragen, was macht an der Stelle sinn. Ich hatte irgendwo gelesen man solle keine Records schicken. Ich frage mich nur was mache ich wenn ich eine Tabelle mit z.B. 10 Spalten und 5000 Zeilen schicken will die der Client darstellen soll. Das kann man doch wohl kaum alles in einem String machen oder etwas doch. Was ich mir vorstelle ist eine flexible art der Kommunikation mit einem Protokoll, wo am Anfang jeder Nachricht zum Server erst mal ein paar Informationen wie z.b. Identität des Clients, der Befehl, evtl. Parameter und falls nötig Daten gesendet werden. Message vom Client zum Server: Zitat:
geht ist eine flexible Kommunikation. Sprich der Server empfängt die Nachricht und entscheidet anhand des Befehls (Protokoll) was zu tun ist, muß jedoch nicht zwischen zig. möglichkeiten der Interpretation der Nachricht welchseln. Frage 2: Kommunikation zwischen Clients und Server. Anhand meiner bisherigen Versuche weiß ich zwar das z.B. OnExecute auf der Serverseite für die Auswertung der Nachrichten der Clients ist, aber wie man da jetzt ansetzt ein Protokoll zu etablieren welches auf Datenstrukturen und nicht auf "simplen" Strings besteht weiß ich nicht. Und wie ich eine Liste der zur Zeit angemeldenten Clients bekomme und ich dann Nachrichten an diese Clients geschickt bekomme. Ich bin über jeden Tipp und vorallem Beispiele dankbar oder wenn jemand entsprechende Tutoriale kennt. Ansonsten noch einen schönen Tag. mfg TUX |
Re: Grundsatz Fragen Client/Server Anw. via Indy10
Wie du ganz richtig erkannt hast ist das Protokoll zwischen Client und Server der eigentliche Knackpunkt.
Der Datentransport über TCP/IP (oder Named Pipes, ser. Schnittstelle,...) ist da eigentlich eher nebensächlich. Es gibt nun verschiedene Arten wie man diese Protokolle aufziehen kann. Eine einfache Art wäre z.B. ein zeilenbasiertes Befehl- und Antwort Protokoll. Ein gutes Beispiel dafür ist ![]() Der Client schickt eine Textzeile (abgeschlossen mit CR-LF) als Befehl und der Server antwortet mit einem Status. Sehr viele Internetprotokolle sind so aufgebaut. Vorteile: einfach, kann mit einer Teminalemulation von Hand gut getestet werden Nachteil: schlecht erweiterbar, unflexibel, nicht für komplexe Daten geeignet Dann gibt es Protokolle, bei denen XML als Grundlage benützt wird. Alle Daten und Befehle werden als XML verpackt und verschickt. z.B. ![]() ![]() Vorteile: beliebig erweiterbar, für komplexe, hierarchische Daten geeignet Nachteile: aufwändig, benötigt hohe Netzbandbreite (ca. 95% der Daten sind "Luft") man kann die XML-Daten vor dem Senden auch komprimieren (zip) und damit den Netzbandbreite reduzieren Eine sehr interessante Variante zu XML ist ![]() Mit JSON kann man auch hierarchische Daten aufbauen ohne so weitscheifend wie XML zu sein. Dann gäbe es noch das ![]() mit dem man Daten binär und kompakt übertragen kann. Der Nachteil von binären Protokollen ist aber, dass man nicht so einfach Debuggen kann. PS: das Schlechteste, was man tun kann ist binäre Records zu übertragen. Das ist zwar schnell programmiert, aber sehr unflexibel und schlecht zu portieren. Verschiedene Programmversionen von Client und Server sind nach Änderungen an den Records nicht mehr kompatibel. Ein gravierender Nachteil dabei ist auch, dass man Client und Server gleichzeitig entwickeln muss. Bei allen textbasierten Protokollen kann man zuerst mit dem Server beginnen. Der Server kann auch leicht mit einem Terminalprogramm getestet werden. |
Re: Grundsatz Fragen Client/Server Anw. via Indy10
Hmmm naja also Probleme mit der Bandbreite sollte es keine geben da es sich um eine reine LAN Anwendung handelt mit
vielleicht 10-20 Clients wobei sicherlich höchstens mal 5 oder 10 Clients gleichzeitig online sind. Die vorteile die für ein Zeilenbasierte Befehl-Antwort Protkoll sprechen sind natürlich nich von der Hand zuweisen. An XML hatte ich dabei noch gar nicht gedacht, da stellt sich natürlich direkt die Frage wie setzt man das ganze um und ist es so perfomant das selbst Tabellen mit mehren Hundert Zeilen noch flüssig übertragen und angezeigt werden können das der Anwender keine oder kaum Verzögerungen spürt. Das ganze kommt auf einen Versuch drauf an. |
Re: Grundsatz Fragen Client/Server Anw. via Indy10
Es wäre gut, wenn du die Enterpriseversion von Delphi hättest.
Dort ist die Klasse TClientDataset dabei. TClientDataset kann ihren Dateninhalt (Felder inkl. Definition + alle Records) als XML laden und speichern. |
Re: Grundsatz Fragen Client/Server Anw. via Indy10
Zitat:
|
Re: Grundsatz Fragen Client/Server Anw. via Indy10
Naja ich hab nicht die Enterprise Version zur Verfügung, daher finde ich den XML Ansatz noch am interessantesten.
Jetzt ist nur die Frage bastel ich mir da selbst was, erzeuge ich immer ein XML Dokument welches ich einfach via Writeln() und Readln() hin und herschicke. Oder kann ich da was fertiges nehmen, so ganz kapieren was dieses XMPP sein soll tu ich noch nicht. Was neben dem Protokoll bzw. der Kommunikation zwischen Client und Server noch wichtig ist, die Verwaltung der Clients auf der Server Seite. Ich hab immer noch nicht raus wie ich auf dem Server eine Liste der zur zeit "angemeldeten" Clients erhalte inkl. möglichkeit diesen auch etwas zuschicken. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:56 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