Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdTCPServer - String an ALLE Clients! (https://www.delphipraxis.net/9601-idtcpserver-string-alle-clients.html)

Holger 29. Sep 2003 23:33


IdTCPServer - String an ALLE Clients!
 
Hi ich will einen Chat schreiben....

dazu hatte ich bisher Sockets benutzt und mit

Delphi-Quellcode:
For I := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
begin // Anzahl der Teilnehmer
with ServerSocket1.Socket.Connections [I] do // Auswahl des Teilnehmers
if (Connected) then SendText(Clientname+': '+msg); // Text senden
end;
diesem Quelltext allen verbundenen Clients die versendeten Nachrichten zugewiesen.

Wie kann ich sowas mit Indys umsetzten das ich an alle verbundenen Clients den gleichen String sende und nicht nur an einen ... ?

Chris1986 1. Okt 2003 15:46

Re: IdTCPServer - String an ALLE Clients!
 
Hallo
Hat keiner eine Idee? Das würde mich nämlich auch mal interessiern. Und wie man mit einer idTCPClient-Kompo überhaupt vernünftig Strings und Commands empfangen und filtern kann, so wie in der Server-Kompo.

Gruß
Christian

Chewie 1. Okt 2003 16:04

Re: IdTCPServer - String an ALLE Clients!
 
Zitat:

Zitat von Chris1986
Und wie man mit einer idTCPClient-Kompo überhaupt vernünftig Strings und Commands empfangen und filtern kann, so wie in der Server-Kompo.

Gar nicht. ClientSockets senden Daten, ServerSockets empfangen sie.

armageddon7007 2. Okt 2003 12:56

Re: IdTCPServer - String an ALLE Clients!
 
Das ganze kann man schon machen und ist eigentlich auch nicht so schwierig.

Habe leider keinen Beispiel-Source, aber mit den Demos von Indy kann man sich das bauen.

Um erstmal alle verbundenen Clients zu ermitteln, gibt es eine einfache Methode, die ich immer benutze.

Zuerst muß man eine eigene Klasse definieren, die zumindest eine Variable vom Typen TIDPeerThread besitzt und ein TList-Object erstellen.
Diese Klasse (hier TClientClass) wird im OnConnect für jede eingehende Verbindung erstellt und der Data-Property von AThread übergeben und der Verweis auf AThread.Data zur Liste (hier fCLientList) hinzugefügt. Dann setzt man im erstellten Object noch die TIDPeerThread-Variable:

Delphi-Quellcode:
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
  AThread.Data:= TClientClass.Create();
  fClientList.Add(AThread.Data);
  TClientList(AThread.Data).faThread:= AThread;
end;
Im OnDisconnect vom Server muß dann dieser Eintrag wieder gelöscht werden. Das vorher erstellte Object braucht man nicht freigeben, das mach AThread alleine, wenn Data<>nil ist. Will man trotzdem das erstellte Object selber freigeben, muß man danach auf jeden Fall Data auf nil setzen.

Delphi-Quellcode:
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
  fClientList.Delete(fClientList.IndexOf(AThread.Data));
end;
Will man nun allen Clients einen String senden, kann man das über das TList-Object machen:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i:=0 to fCLientList.Count-1 do begin
    if TClientClass(fClientList[i]).fAThread.Connection.Connected then begin
      TClientClass(fClientList[i]).fAThread.Connection.WriteLn('Hallo');
    end;
  end;
end;


Im Client sieht das dann schon ein bißchen anders aus, dort muß man einen Thread erstellen, der die ganze Zeit ein Read vom IDTCPCLient macht. Dazu sollte man den Wert von ReadTimeOut auf jeden Fall sehr niedrig setzen (z.B. 250ms).
Zudem braucht man eine Semaphore, mit der man absichert, dass der Thread nur dann ein Lesebefehl ausführt, während von anderen Programmteilen nichts gesendet oder gelesen wird.

Dann locked man die Semaphore wenn man selber etwas senden oder lesen möchte und in der Zeit wird der Thread nicht versuchen, etwas zu lesen, da dieser natürlich :tongue: auch versucht die Semaphore zu bekommen, bevor dieser versucht etwas vom idTCPClient zu lesen.

Damit sollte das eigentlich klappen.

Hoffe du kannst damit was anfangen, ansonsten habe ich die tage bestimmt mal zeit ein kleines Demo zu schreiben.

EConvertError 25. Okt 2003 18:59

Re: IdTCPServer - String an ALLE Clients!
 
Hallo!

Ich möchte auch einen Chat schreiben (scheinbar ein sehr beliebtes Projekt :) ).

Das mit dem Server habe ich auch ohne Hilfe geschafft, nur folgendes ist mir etwas unklar:

Zitat:

Im Client sieht das dann schon ein bißchen anders aus, dort muß man einen Thread erstellen, der die ganze Zeit ein Read vom IDTCPCLient macht.
Befindet sich der IdTCPClient direkt im Thread, oder außerhalb?
Und macht der Thread nur ReadLn(), oder ist er auch für das schreiben (z.B. WriteLn) verantwortlich?

Schon jetzt vielen Dank für eure Hilfe!

EConvertError

Kamil 25. Okt 2003 19:04

Re: IdTCPServer - String an ALLE Clients!
 
IdTCPClient muss im Thread definiert sein und ist für Empfangen und Senden verantworlich

EConvertError 25. Okt 2003 19:04

Re: IdTCPServer - String an ALLE Clients!
 
Danke.

mfg, EConvertError

tria1312 5. Okt 2005 07:33

Re: IdTCPServer - String an ALLE Clients!
 
Hi armageddon,

Ist zwar zeimlich lange her dein Thread, aber vielliecht erinnerst du dich ja noch.

In der Methode OnConnect schreibst du die Daten des Thread in ein Listenobject:
fClientList.Add(AThread.Data);

Genau an dieser Stelle schmiert meine Anwendung ab. Habe ich vielleicht etwas mit der Client-Klasse falsch gemacht?
Hier ist meine Klasse:
Delphi-Quellcode:
type
  TIdClientClass = class
    IdPeedThread : TIDPeerThread;
  end;

Danke

tria1312

tria1312 5. Okt 2005 08:40

Re: IdTCPServer - String an ALLE Clients!
 
Sorry, man muss natürlich das TList-Object vorher initialisieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:49 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