Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Users online in einem Chat (https://www.delphipraxis.net/25267-users-online-einem-chat.html)

ArmyMan 3. Jul 2004 20:32


Users online in einem Chat
 
Hallo zusammen

Ich habe ein problem.
Ich versuche schon ewig lang, einen chat zu programmieren wo man sieht wer online ist.
Ich muss nur dass mit dem online haben, nicht das man jedem einzeln schreiben kann. Es wird immer allen teilnehmern geschrieben.

Bitte helft mir, Danke

ArmyMan

Christian Seehase 3. Jul 2004 20:35

Re: Users online in einem Chat
 
Moin ArmyMan,

nur mal so als Idee:
Wenn der Chat mit Server und Client arbeitet, müsstet Du, vom Server aus, nur jede An-/Abmeldung an jeden angemeldeten Client weiterschicken.

ArmyMan 3. Jul 2004 20:39

Re: Users online in einem Chat
 
Könntest du mir einen quelltext schreiben bitte. Ich habe einen riesigen knopf :drunken:

Thx ArmyMan

Christian Seehase 3. Jul 2004 20:49

Re: Users online in einem Chat
 
Moin ArmyMan,

Zitat:

Zitat von ArmyMan
Es wird immer allen teilnehmern geschrieben.

das hast Du doch schon geschrieben.
Du musst lediglich eine Kennung (Kommando) mit übertragen, dass es sich nicht um einen Chattext handelt, sondern um eine Info, in diesem Falle also einen Zu-/Abgang bei den Teilnehmern.

Phoenix 3. Jul 2004 21:07

Re: Users online in einem Chat
 
:warn:
Zitat:

Zitat von ArmyMan
Könntest du mir einen quelltext schreiben bitte.

Zitat:

Zitat von Verhaltenskodex der DP
2.3.2.3 - Null Bock? Nicht hier.

Mit Fragen, die sich lesen wie "...ich habe weder Ahnung noch Lust, kann mir mal einer mein Programm schreiben..." wirst Du hier nicht auf Gegenliebe stoßen. Wir sind gerne bereit, jedem zu helfen, der selber Engagement zeigt - aber wir machen nicht die Hausaufgaben Anderer.
Zudem ist es unerläßlich, daß Du Dich selber mit dem Problem befasst hast, bevor Du in der Lage bist, dazu eine präzise Frage zu stellen.
Etwas völlig Anderes ist es natürlich, wenn Du (noch) nicht weißt, wonach Du suchen sollst, bzw. wo Du anfangen sollst. Dann frage gerne nach geeigneten Stichworten.


ArmyMan 3. Jul 2004 21:45

Re: Users online in einem Chat
 
Sorry, es ist nicht dass ich kein bock habe, aber ich weiss nicht wie es geht.

Server:
Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdIPWatch, ScktComp, StdCtrls,
  ExtCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    ServerSocket1: TServerSocket;
    IdIPWatch1: TIdIPWatch;
    lblip: TLabel;
    Panel1: TPanel;
    ListBox1: TListBox;
    Edit1: TEdit;
    Button1: TButton;
    ClientSocket1: TClientSocket;
    ListBox2: TListBox;
    procedure FormActivate(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    function GetToken(aString, SepChar: string; TokenNum: Byte): string;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
begin
lblip.Caption := IdIPWatch1.LocalIP;
clientsocket1.Host := IdIPWatch1.LocalIP;
clientsocket1.Active := true;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var i :integer;
    Text:string;
    nickname: string;
    message: string;
begin
Text:=Socket.ReceiveText;
nickname := (Trim(GetToken(Text,': ',1)));
message := (Trim(GetToken(Text,': ',2)));
begin
 Memo1.Lines.add(Timetostr(now) + ': '+ nickname + ': ' + message);
  For I := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
   begin
   with ServerSocket1.Socket.Connections [I] do
  if (Connected) then SendText(nickname + ': ' + message);
 end;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
serversocket1.Close;
memo1.Lines.SaveToFile('chat-log.txt');
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ListBox1.Items.Delete(ListBox1.Items.IndexOf(Socket.RemoteAddress+'('+Socket.RemoteHost+')'));
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var nickname: string;
    text: string;
begin
Text := Socket.ReceiveText;
nickname := (Trim(GetToken(Text,': ',1)));
ListBox1.Items.Add(Socket.RemoteAddress + nickname);
end;

function TForm1.GetToken(aString, SepChar: string; TokenNum: Byte): string;
var
  Token: string;
  StrLen: Byte;
  Num: Byte;
  EndofToken: Byte;
begin
  StrLen    := Length(aString);
  Num       := 1;
  EndofToken := StrLen;
  while ((Num <= TokenNum) and (EndofToken <> 0)) do
  begin
    EndofToken := Pos(SepChar, aString);
    if EndofToken <> 0 then
    begin
      Token := Copy(aString, 1, EndofToken - 1);
      Delete(aString, 1, EndofToken);
      Inc(Num);
    end
    else
      Token := aString;
  end;
  if Num >= TokenNum then
    Result := Token
  else
    Result := '';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if (clientsocket1.Active = true) and (edit1.Text <> '')
then clientsocket1.Socket.SendText('console: ' + edit1.Text);
edit1.Clear;
edit1.SetFocus;
end;

end.
Client:
Delphi-Quellcode:
implementation

uses mainemail;

{$R *.dfm}

procedure TTDP_MultiTool.delay(time: word);
var start: integer;
begin
  start := GetTickCount;
  while (GetTickCount)-(Start) <= time do
  application.ProcessMessages;
end;

procedure TTDP_MultiTool.lblcloseClick(Sender: TObject);
begin
close;
end;

procedure TTDP_MultiTool.editmessageChange(Sender: TObject);
begin
if editmessage.Text = ''
then btnsend.Enabled := false
else btnsend.Enabled := true;
if memochat.Modified
then tab1.ActivePage := 'Chat';
end;

procedure TTDP_MultiTool.btnloginClick(Sender: TObject);
begin
clientsocket1.Open;
delay(2000);
if clientsocket1.Active
then
  btnlogoff.BringToFront
else
  begin
  clientsocket1.Close;
  lbonline.Clear;
  application.MessageBox('Server not online', 'Error', 0+64);
  end;
end;

procedure TTDP_MultiTool.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
clientsocket1.Socket.SendText(lblusername.caption + ' has logged on');
editmessage.Enabled := true;
editmessage.SetFocus;
end;

procedure TTDP_MultiTool.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
btnlogoff.Click;
end;

procedure TTDP_MultiTool.btnlogoffClick(Sender: TObject);
begin
clientsocket1.Socket.SendText(lblusername.caption + ' has logged off');
delay(500);
clientsocket1.Close;
btnlogin.BringToFront;
end;

procedure TTDP_MultiTool.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memochat.Lines.Add(socket.ReceiveText);
end;

procedure TTDP_MultiTool.btnsendClick(Sender: TObject);
begin
if clientsocket1.Active
then
  begin
  editmessage.SetFocus;
  clientsocket1.Socket.SendText(lblusername.caption + ': ' + editmessage.Text);
  editmessage.Clear;
  editmessage.SetFocus;
  end
else
  btnlogin.SetFocusl
end;

procedure TTDP_MultiTool.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
lbonline.Clear;
editmessage.Enabled := false;
end;

end.
Wo kann ich dass mit dem Info senden einfügen?

ArmyMan

alcaeus 4. Jul 2004 06:16

Re: Users online in einem Chat
 
Ok, nachdem ich diesen Thread auch endlich gefunden habe, kann ich dir weiterhelfen.
Ich habe in meinem Chat Konstanten definiert, mit welchen festgestellt werden kann, was zur Zeit passiert. Dies muss dan alles mit Hilfe von Trennzeichen wieder aufgespaltet werden.

Für einen Text sieht das dann ungefähr so aus:
Wichtig: Die Codes sind nicht Copy-Paste-Codes :!:
Delphi-Quellcode:
...SendText(IntToStr(TEXT)+cDelimiter+strText);
TEXT ist die Konstante, die bedeutet, dass ein Text folgt. cDelimiter ist die Konstante für das Trennzeichen und strText ist der Text der gesendet wird.

Fürs An/Abmelden eines Users könnte alles dann wie folgt aussehen:
Delphi-Quellcode:
...SendText(IntToStr(LOGON)+cDelimiter+strUsername);
...SendText(IntToStr(LOGOFF)+cDelimiter+strUsername);
Das kommt in jene Routine rein, wo ein User beim Server hinzugefügt bzw. gelöscht wird.

Ein Problem hast du nun aber noch. Wenn sich ein neuer Client anmeldet, dann muss dieser auch erfahren, wer bereits im Chat ist. Ich habe das Problem so gelöst. Sobald sich ein Client anmeldet, wird dem Benutzer eine Nachricht geschickt (mit einer Konstante wie oben), damit er weiß dass die Userliste kommt. Anschließend wird mit einer while-Schleife das User-Array abgegangen und Stück für Stück dem User gesendet. Du kannst dies auch anders lösen, indem du die User auf einmal sendest, aber das bleibt dir überlassen. Anschließend wird das Abschlusskommando gesendet, und dabei zur Kontrolle auch die Userzahl mitgegeben.

Ich hoffe ich habe dir irgendwie geholfen, wenn nicht dann frag nur.

Greetz
alcaeus

PS: Poste langen Code bitte nicht in den Beitrag, sondern als Dateien.

ArmyMan 4. Jul 2004 10:31

Re: Users online in einem Chat
 
Tut mir leid. Aber jetzt komm ich noch weniger draus.
Ich dachte ich machs so:

Wenn ein neuer client anmeldet, schickt es die ganze user liste an alle clients. Also wenn sich einen client anmeldet, copiert es die ganze listbox und schick sie zur listbox von dem client. Geht dass überhaupt??

Danke für deine hilfe

ArmyMan

vlees91 4. Jul 2004 10:49

Re: Users online in einem Chat
 
Hi,

ich hab letztens einen chat geschrieben (mit den WinSockets) (in freeware).
da wird bei jeder anmeldung das handle vom client gespeichert und wenn jemand etwas schreibt, wird automatisch das handle mitgeschickt und man kann kontrollieren, wer es war (ich hab die handles in einem array gespeichert)
in einem anderen array speichert man die nicks und wenn jetzt der user mit dem handle "123456" etwas schreibt wird mit einer schleife das handle "123456" im handle-array gesucht und die stelle(id), an der das handle in dem array steht, muss dann wieder im nick-array gesucht werden.
z.B. HAndle:123456
handle-array:hat die 3. stelle(also hat sich als viertes angemeldet(0 zählt auch))
suche im nick-array bei stelle 3:dort steht z.b. Max Mustermann.

alcaeus 4. Jul 2004 10:50

Re: Users online in einem Chat
 
Naja, knapp daneben ist auch vorbei.
Wenn ein Client sich anmeldet, so schickt der Server dem neu angemeldeten Client die gesamte Userliste (der neue Client ist darin noch nicht enthalten).
Anschließend schickt der Server den Namen (und evtl. auch weitere Daten) and alle Clients, die dann die Meldung ausgeben "xy hat den Chat betreten." Dasselbe geschieht auch beim neuesten Client, aber das könntest du u.U. auch ausblenden. IMHO geht es so aber am einfachsten.

Greetz
alcaeus

vlees91 4. Jul 2004 11:03

Re: Users online in einem Chat
 
wie? knapp daneben ist auch vorbei?

du weißt doch garnicht, wie ich das gemacht habe. oder hast du das in assembler decompiled und dann nach pascal :?: :stupid:

ArmyMan 4. Jul 2004 11:13

Re: Users online in einem Chat
 
Hi Vlees

Das mit den arrays verstehe ich nicht ganz. Kann man nicht den ganzen inhalt einer ListBox and den client ListBox weiterschicken?
Wäre am einfachsten für mich. Ich bin kein DelphiPro wisst ihr. Ich habe versucht die Strings einer ListBox als text an alle clients zu schicken und dort in die ListBox von dem client hinein zu schreiben. Dass muss doch gehen. Wenn nicht, kann mir jemand dass mit den arrays genau erklären?

Thx ArmyMan

alcaeus 4. Jul 2004 11:13

Re: Users online in einem Chat
 
Vlees, dein Posting kam während ich die Antwort auf ArmyMans Beitrag geschrieben habe, sorry.
Zu deinem Vorschlag: Er will auf den Clients eine Liste mit allen Benutzern halten. Dein Lösungsansatz beschreibt das für den Server, sein Problem ist aber, dass er den Clients mitteilen muss "jetzt ist ein neuer Client da" bzw. dem neuen Client die gesamte Userliste senden muss.

Greetz
alcaeus

ArmyMan 4. Jul 2004 11:14

Re: Users online in einem Chat
 
Ja genau dass will ich :lol:

Erklärung bitte. Weiss nicht wie ich dass anstelle

ArmyMan

Aenogym 4. Jul 2004 11:30

Re: Users online in einem Chat
 
hi armyman,

also du kannst den inhalt einer listbox als string verschicken. musst nur irgendwie mitschicken, dass es sich um die client-liste handelt und nicht um eine chat-nachricht.

den inhalt einer listbox als string bekommst du so:
Delphi-Quellcode:
listbox1.items.commatext
wie gesagt einfach diesen wert versenden und und beim client wieder so einfügen;

Delphi-Quellcode:
listbox1.items.commatext := recievetext;
:thuimb: Aenogym

ArmyMan 4. Jul 2004 11:49

Re: Users online in einem Chat
 
Thx, aber wenn ich dass so schicke kommt der inhalt des ListBoxes in das chat memo feld, oder alles in die ListBox. Dass will ich nicht. Ich will dass so:

ListBox -> ListBox
Server Memo -> Client Memo

Thx ArmyMan

alcaeus 4. Jul 2004 11:51

Re: Users online in einem Chat
 
Ich zitier mich mal selber:
Zitat:

Zitat von alcaeus
Ich habe in meinem Chat Konstanten definiert, mit welchen festgestellt werden kann, was zur Zeit passiert. Dies muss dan alles mit Hilfe von Trennzeichen wieder aufgespaltet werden.

Für einen Text sieht das dann ungefähr so aus:
Wichtig: Die Codes sind nicht Copy-Paste-Codes :!:
Delphi-Quellcode:
...SendText(IntToStr(TEXT)+cDelimiter+strText);
TEXT ist die Konstante, die bedeutet, dass ein Text folgt. cDelimiter ist die Konstante für das Trennzeichen und strText ist der Text der gesendet wird.

Fürs An/Abmelden eines Users könnte alles dann wie folgt aussehen:
Delphi-Quellcode:
...SendText(IntToStr(LOGON)+cDelimiter+strUsername);
...SendText(IntToStr(LOGOFF)+cDelimiter+strUsername);
Das kommt in jene Routine rein, wo ein User beim Server hinzugefügt bzw. gelöscht wird.

Versuch mal diese Konstantenzeug zu implementieren, das ist nämlich genau das was du machen musst.

Greetz
alcaeus

ArmyMan 4. Jul 2004 12:00

Re: Users online in einem Chat
 
Das verstehe ich überhaupt nicht! :wall:
Ich weiss nicht wie dass geht. Habs probiert aber ich kann nicht mal kompilieren, etwas ist falsch :evil:

Ich brauche eine andere möglichkeit, oder eine SEHR genaue erklärung.

Danke
ArmyMan

alcaeus 4. Jul 2004 12:04

Re: Users online in einem Chat
 
Erklär mal bitte genau was nicht funktioniert. Wenn ich eine Fehlermeldung etc. sehe, dann geht das leichter.
Hast du auch die entsprechenden Konstanten definiert?
Hast du deine Variablen eingesetzt?
Vielleicht ist es wirklich nur was kleines wie oben.

Greetz
alcaeus

ArmyMan 4. Jul 2004 12:07

Re: Users online in einem Chat
 
Ich verstehe dass was du geschrieben hast nicht. Ich verstehe den code nicht. Ich weiss gar nicht wo ich ihn einsetzen muss.
:wiejetzt:
ich muss nur wissen wo dass zeug hingehört, dann gehts vielleicht.

Thx ArmyMan

alcaeus 4. Jul 2004 12:10

Re: Users online in einem Chat
 
Ok, dann versuch ichs nochmal.

Du musst unterscheiden können, ob es jetzt ein Text für das Memo oder etwas für die Liste ist. Also musst du vorne etwas an den Text hängen. Sobald der Server was sendet, so kannst du dem Text z.B. "MEMO" oder "LIST" voraussetzen.
Sobald der Client die Daten erhält, so muss er diese ersten 4 Zeichen ansehen. Mit Copy kopierst du die raus, anschließend löschst du sie mit Delete. Ist die kopierte Zeichenkette "MEMO" so ist es ein Text und er geht ins Memo, wenn er "LIST" ist, dann musst du was mit den Daten anfangen, je nachdem wie du sie aneinanderhängst also wieder trennen.
Ich hab hier leider kein Delphi, sonst würde ich dir auch den Code hinschreiben.

Greetz
alcaeus

Tubos 4. Jul 2004 12:12

Re: Users online in einem Chat
 
Zitat:

Ich brauche eine andere möglichkeit, oder eine SEHR genaue erklärung.
Das ist die beste Möglichkeit.
Genauso mache ich es in meinem Chat auch.

Definiere Konstanten und sende immer eine Konstante und einen Parameter.
Bei mir gibt es zum Beispiel konstanten wie

const MsgUser='*user:';
// Eingabe

const MsgQuit='*quit:'
// Jemand verlässt den chat

usw...

bin erst ganz am anfang, aber das Konzept sieht ungefähr so aus.
Jetzt kombiniere ich die und sende z.B. MsgQuit+'Tubos'.
Durch folgende Funktionen kann ich die Nachricht (msg) oder den parameter (par) herausfiltern:

Delphi-Quellcode:
function msg(s: string): string; // extrahiert die Nachricht aus dem empfangenen String
begin
 result:=copy(s,1,pos(':',s));
end;

function par(s: string): string; // extrahiert den Parameter aus dem empfangenen String
begin
 result:=copy(s,pos(':',s)+1,999);
end;
(Nicht alle MSGs haben Parameter.)



Wenn ich einen String bekomme, der in der Variablen x gespeichert wird mache ich folgendes:
Delphi-Quellcode:
if msg(x)=MsgQuit then memo1.lines.add(par(x) + ' verlässt den Chat.');
Natürlich muss ich den Eintrag aus der Listbox mit den Usern noch entfernen, aber das ist nur zur Erklärung wie so ein Nachrichtensystem funktionieren kann.

Hoffe das hat dir ein wenig geholfen und dich nicht noch mehr verwirrt :wink:

ArmyMan 4. Jul 2004 12:15

Re: Users online in einem Chat
 
Beides :roll:

Wo muss ich das zeug hineinschreiben?? OnClientRead, OnClientConnect, OnClientDisconnect??
Heute hab isch einen RIISEN knopf :(

Thx ArmyMan

alcaeus 4. Jul 2004 12:24

Re: Users online in einem Chat
 
Alles wo die Konstanten reingegeben werden müssen kommt dahin, wo du Socket.SendText aufrufst.
Das Auslesen der Konstante oder so kommt beim OnClientRead des Client-teils rein.

Greetz
alcaeus

ArmyMan 4. Jul 2004 14:25

Re: Users online in einem Chat
 
Ich bin glaube zu blöde... :pale:
Ich verstehe es einfach nicht.

Wenn jemand einen quelltext in diesem stil hat bin ich offen. Ich verstehe den zusammenhang eben nicht. Wenn ich ihn sehe clickt es vielleicht.

Danke für euere hilfe
ArmyMan

alcaeus 4. Jul 2004 15:17

Re: Users online in einem Chat
 
Zuerst musst du mal einige Konstanten definieren:
Delphi-Quellcode:
const
  cFinish = #1;
  Kommando_1 = 'KOMM1';
  Kommando_2 = 'KOMM2';
  MaxArguments = 25;
Diese Konstante brauchst du noch. Bedenke dass du die Konstanten für Befehle beliebig erweitern kannst, diese aber im Server und im Client gleich sein müssen (falls du es getrennt hast).

So werden die Befehle zusammengesetzt:
Delphi-Quellcode:
Socket.SendText(Kommando_1+cFinish+'Param_1'+cFinish´'Param_2'+cFinish);
Hier musst du beachten, dass jeder Befehl mit cFinish abgeschlossen werden muss. Zweitens muss zwischen allen Parametern und dem Befehl ein cFinish stehen. Aufgrund dieses Zeichens wird der Text wieder getrennt.

Das ist die Prozedur zum Aufspalten eines Zusammengesetzten Befehls.
Delphi-Quellcode:
var
  Arguments: array[1..MaxArguments] of String;
  Command: String;
  i: Integer;
  NumArguments: Integer;
begin
  Data := Socket.ReceiveText;
  Command := Copy(Data,1,Pos(cFinish,Data)-1);
  Delete(Data,1,Pos(cFinish,Data));
  NumArguments := 0;
  while Length(Data) > 0 do
  begin
    Inc(NumArguments);
    Arguments[NumArguments] := Copy(Data,1,Pos(cFinish,Data)-1);
    Delete(Data,1,Pos(cFinish,Data));
  end;
end;
Das Codesegment musst du dir unter Umständen noch bearbeiten. In Command wird am Ende dann das Kommando (also der erste Parameter) drinstehen, Arguments[i] enthält den jeweiligen Parameter, und NumArguments die Anzahl Parameter. Du kannst den Code auch so umbauen, dass er mit dynamischen Arrays und nicht der vordefinierten Höchstanzahl funktioniert. Wie gesagt, der Code ist noch uneffizient, ich habe lange nicht mehr am Chat gearbeitet. Weiters könnte man es auch einfacher aufspalten, such dazu mal im Forum nach DelimitedText.
Ich hoffe dass dir diese Codefragmente weiterhelfen, ich hoffe du weißt auch wo du sie einbauen musst.

Greetz
alcaeus

ArmyMan 21. Jul 2004 16:08

Re: Users online in einem Chat
 
Ich sehe es nicht! Sorry

Vergisst es. Ich schaffe es nicht

Greez ArmyMan


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