Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem mit Programminternem Chat (https://www.delphipraxis.net/125542-problem-mit-programminternem-chat.html)

5etH 8. Dez 2008 09:14


Problem mit Programminternem Chat
 
Hallo Zusammen,

momentan arbeite ich an einem chat der sich in einem anderem Programm von mir abspielt

Also ich kann ohne Probleme mittlerweile einen "Raum" erstellen in den die leute rein können und miteinander schreiben können,
aber leider gelingt es mir nicht einen "privaten" chat zu erstellen

ich habe versucht den server auf dem mainform laufen zu lassen was sich aber als unsinnig herraustellte sobald mehrere dem selben schreiben wollten da alles dann in einem chatfenster passierte

wie kann ich eine guteb Privatechat bauen ich arbeite momentan mit sockets... gibts da auch eine andere Möglichkeit. ich bin langsam am ende mit meinen ideen

wie gesagt ist der socketserver server auf dem mainform und schreibt auf einen server seinen nick um den anderen zu zeigen "hey bin online" worauf hin andere ihm schreiben können

der socketclient liegt auf einem chatfenster was zur laufzeit kreiert wird.

wenn weitere fragen offen stehen versuche ich sie zu beantworten


gruß 5etH

Sir Rufo 8. Dez 2008 09:50

Re: Problem mit Programminternem Chat
 
Also ich würde ja nur mit einem einzigen Socket-Server arbeiten.

Alles was dort ankommt wird entsprechend interpretiert bzw. entsprechend verteilt.

In die Nachricht würde ich zudem auch die Routing-Information einbetten (Raum oder Privat) und dann im entsprechenden Fenster anzeigen.

cu

Oliver

5etH 8. Dez 2008 09:52

Re: Problem mit Programminternem Chat
 
ich kann aber leider nicht nur mit einem server arbeiten da das Programm nicht von einem server abhängig sein soll... gibts denn sonst keine möglichkeit das programmintern zu verwallten ... bzw wie kann ich denn ermitteln wer mir gerade schreibt das würde mir auch schon helfen

Sir Rufo 8. Dez 2008 10:00

Re: Problem mit Programminternem Chat
 
Zitat:

Zitat von 5etH
ich kann aber leider nicht nur mit einem server arbeiten da das Programm nicht von einem server abhängig sein soll...

Was hat das den damit zu tun :gruebel:
Das ist doch nur eine Komponente mit einem festen Port, mehr nicht. Alles andere hat ja nur was mit dem Konzept zu tun (ob ich also etwas serverbasierend aufbaue).
Zitat:

Zitat von 5etH
gibts denn sonst keine möglichkeit das programmintern zu verwallten ... bzw wie kann ich denn ermitteln wer mir gerade schreibt das würde mir auch schon helfen

Wenn du eine nachricht empfängst, dann wird doch ein Event ausgelöst und das Event hat einen Socket-Parameter und da steht u.a. drin, von welchem Rechner das jetzt kommt. Ansonsten pack das doch einfach in die Nachricht mit rein!

Beispiel-Nachricht 1:
Code:
From:MasterBlaster
Room:Wir hier ganz alleine
Msg:Ey oller alles fit?
Beispiel-Nachricht 2:
Code:
From:MasterBlaster
Private
Msg:Mas was privates
Wie du die Nachricht aufbaust und drauf reagierst, bleibt doch dir ganz allein überlassen. Der Server-Socket bietet dir nur die Transport-Schicht. Was du transportierst ist dem sowas von egal :mrgreen:

cu

Oliver

5etH 8. Dez 2008 10:31

Re: Problem mit Programminternem Chat
 
ja das hat mir schonmal weiter geholfen nun stehe ich aber vor dem problem das wenn der server eine nachricht bekommt das passende Form zu ermitteln, da ich sie ja zur laufzeit erzuge

also momentan sied das zum trennen zuständige codestück so aus
Delphi-Quellcode:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var da : Boolean;
  I: Integer;
begin
da := false;
for I := 0 to stringgrid3.rowcount - 1 do
begin
  if stringgrid3.Cells[0,i] = socket.remoteaddress then
  begin
    da := true
  end;
end;
  if not da then
  begin
    with Tform11.Create(Application) do
  begin
    Show();
    Memo1.Lines.Add(Socket.ReceiveText);
    caption := 'Chat mit '+socket.RemoteHost;
    if stringgrid3.Cells[0,0] = '' then
    begin
     stringgrid3.Cells[0,0] := socket.RemoteAddress;
    end
    else
    begin
       stringgrid3.Cells[0,stringgrid3.RowCount -1] := socket.RemoteAddress;
    end;
  end;
  end
  else
  begin
    //hier müsste ich wissen an welches form es dann muss
  end;

Sir Rufo 8. Dez 2008 11:22

Re: Problem mit Programminternem Chat
 
Zitat:

Zitat von 5etH
ja das hat mir schonmal weiter geholfen nun stehe ich aber vor dem problem das wenn der server eine nachricht bekommt das passende Form zu ermitteln, da ich sie ja zur laufzeit erzuge

Merk dir einfach welche Form was anzeigen soll z.B. in einer TObjectList ... ist für das entsprechende Thema keine Form da, dann erzeug einfach eine Form (und natürlich in der Liste merken)

cu

Oliver

5etH 8. Dez 2008 11:31

Re: Problem mit Programminternem Chat
 
ja soweit habe ich auch schon gedacht bin aber auf das problem gestoßen das ich nicht weis wie ich dann auf das speziefische memo zugreifen soll :(

Sir Rufo 8. Dez 2008 11:37

Re: Problem mit Programminternem Chat
 
na wegen OOP macht das doch keine Probleme, oder?

Du solltest ja immer das gleiche Ursprung-Form benutzen:
Delphi-Quellcode:
TChatForm = class( TForm )
    Memo1 : TMemo;
  private
  public
  end;
und dann:
Delphi-Quellcode:
TChatForm( FormListe.Object[ FormIndex ] ).Memo1
Wenn du die Form-Klasse auch noch um entsprechende Propertys erweiterst (sind hier jetzt die privaten Nachrichten, welcher Raum, etc.) dann kannst du darüber auch herausfinden, ob es das richtige Form ist. Und wenn nicht, dann eins anlegen in die Liste eintragen und dann in das Memo-Feld übergeben.

5etH 8. Dez 2008 11:56

Re: Problem mit Programminternem Chat
 
Liste der Anhänge anzeigen (Anzahl: 1)
mir wächst das ganze momentan voll über den kopf ich werde jetzt erstmal eine testexe machen das nur zum chatten ist bevor ich es in mein programm implimentiere sonst werde ich verrückt dann kann ich diese auch posten mit quelltext ich hoffe das mir dann besser zu helfen ist

gruß Manu


EDIT: so ich bin jetzt so weit wie ich ohne hilfe kommen kann. im anhang ist sowol Quelltext als auch Exe ich hoffe das ihr mir weiter helfen könnt

bekannte fehler:

1. der übergebene Host auf dem dynamisch erzeugten Form löscht sich!

2. ich kann nicht schreiben sondern nur empfangen wenn ich mit mir schreibe!

3. die formlist wird beim ersten eintrag schon gesprengt ??

hab nochmal die neue hochgeladen

Sir Rufo 8. Dez 2008 13:03

Re: Problem mit Programminternem Chat
 
Du übergibst der Formlist das Object Self, das bezieht sich aber auf Form1!

Warum/Wofür auf dem Form2 ein ClientSocket?? Alles über einen ServerSocket laufen lassen!

Im Form2 ist keine Möglichkeit überhaupt was zu senden (also ich sehe da nix von wegen senden)

EDIT:

Pack doch mal den ServerSocket in eine DatenUnit, die bindest du dann in Form1 und Form2 ein (Form2 ist da eigentlich am wichtigsten, weil das Chatten über das Form2 läuft). Dann kannst du nachher auch das ganz einfach in dein anderes Projekt übernehmen

5etH 8. Dez 2008 13:05

Re: Problem mit Programminternem Chat
 
das mit dem senden habe ich eben selbst bemerkt und geändert :oops:

aber ich brauch das einen client ohne geht das doch garnet :?:

soll ich einfach statt self ... form2 übergeben ?

Sir Rufo 8. Dez 2008 13:13

Re: Problem mit Programminternem Chat
 
Zitat:

Zitat von 5etH
das mit dem senden habe ich eben selbst bemerkt und geändert :oops:

aber ich brauch das einen client ohne geht das doch garnet :?:

soll ich einfach statt self ... form2 übergeben ?

Dat Client-Ding ist ein abgespecktes Server-Ding, der Server kann alles was der Client kann (senden, empfangen) und etwas mehr ;) also nicht notwendig

aber nicht form2 übergeben sondern du erzeugst ja mit TForm2.Create ein Form und die Referenz auf das Object!
also
Delphi-Quellcode:
FormIndex := FormList.Add( TForm2.Create )
dann kannst du mit
Delphi-Quellcode:
TForm2( FormList[ FormIndex ] )
weiterarbeiten (den genauen Zugriff findest du über die Online-Hilfe zu TObjectList, kein Delphi grad offen :mrgreen: )

Dem Formular solltest du auch noch die Daten vom Partner übergeben (Steht im Recieve-Event Socket), damit du darauf auch antworten kannst.
Um zu antworten einfach aus dem Form2 den ServerSocket benutzen und an den übergeben Empfänger zurückschicken.

Sollten sich da mehrere Empfänger pro Raum/Private Nachricht aufhalten, dann musst du in dem Chat-Fenster auch eine ClientListe führen (analog zu der FormListe) und dann an alle senden.

cu

Oliver

EDIT:

Schau dir mal die Funktionsweise von Skype (o.ä.) an, das Haupt-Fenster zeigt dir nur die Buddy-Liste an, der Chat selbst geht über ein eigenes Chat-Fenster ;) also so wie hier vorgeschlagen.

5etH 8. Dez 2008 13:22

Re: Problem mit Programminternem Chat
 
bei dem befehl sacht er mir das ich nicht genügend wirkliche parameter übergebe aber in der hilfe steht das er nicht mehr will als den ???

Delphi-Quellcode:
counter := FormList.Add(TForm2.Create);

Sir Rufo 8. Dez 2008 13:44

Re: Problem mit Programminternem Chat
 
FormList.Add will keine weiteren Parameter aber TForm2.Create braucht einen Parameter ;)
Da kannst du nil nehmen, musst dich aber dann um das Entfernen des Forms selber kümmern, was in diesem Fall auch besser ist, weil das Form ja in der FormList enthalten ist.

5etH 8. Dez 2008 13:59

Re: Problem mit Programminternem Chat
 
Liste der Anhänge anzeigen (Anzahl: 1)
also ich kann immernoch nur eine nachricht schicken dann nixmehr ... nehme an das es mit der objectlist zusammenhängt ... wahrscheinlich kein abgleich

da werde ich mal jetzt genauer debuggen

habs aber totzdem nochmal hier hochgeladen falls dir ja was auffällt

aber auf jedenfall schonmal vielen vielen vielen dank das du dir so viel zeit für mich genommen hast ;)

gruß manu

5etH 8. Dez 2008 14:10

Re: Problem mit Programminternem Chat
 
mir ist aufgefallen das in DATA onclientread das receivetext in zeile 69 leer ist ????

wie kann das denn sein ?

Sir Rufo 8. Dez 2008 14:14

Re: Problem mit Programminternem Chat
 
Du benutzt ja immer noch den ClientSocket im ChatForm.
Verleg den ganzen Verwaltungskram für den Chat nach DATA.pas (schon wegen der Trennung Anzeige, Verarbeitung)

Wofür brauchst du die Variable counter in der Klasse? Die Variable wird doch nur in der Function benutzt, kann also dort deklariert werden, und vor allem nicht in Form1 (s.o.). Wenn du wissen willst wieviele Forms in FormList sind, dann kannst du das über FormList.Count abfragen!
Und dann würde ich die Variable auch FormIndex nennen, weil in der Variable ja nix gezählt werden soll ;)

Sir Rufo 8. Dez 2008 14:15

Re: Problem mit Programminternem Chat
 
Zitat:

Zitat von 5etH
mir ist aufgefallen das in DATA onclientread das receivetext in zeile 69 leer ist ????

wie kann das denn sein ?

Weil du immer noch mit diesem komischen ClientSocket arbeitest! Mach den weg und lass alles zentral über den ServerSocket laufen!

EDIT:

Pro Chat-Fenster hast du ja sonst eine Verbindung stehen, was völlig überflüssig ist. Auch die Anzahl der Ports (jeder ClientSocket belegt einen) ist begrenzt, sind zwar ne Menge aber begrenzt. Ein ServerSocket -> Ein Port fertig.

5etH 8. Dez 2008 14:27

Re: Problem mit Programminternem Chat
 
Liste der Anhänge anzeigen (Anzahl: 1)
also meiner meinung nach brauche ich einen client weil ich sonst ja garkeine verbindung erstellen kann

aber nagut kannst mich ja überzeugen ... hab den jetzt komplett raus und jetzt siehts echt düster aus weil jetzt schickt er garnichts mehr :cry:

hier nochmal das aktuelle programm ohne Client

Sir Rufo 8. Dez 2008 15:00

Re: Problem mit Programminternem Chat
 
in der DATA.pas
Delphi-Quellcode:
procedure TDataModule3.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
Den Socket den du da bekommst, den übergib mit an das Form2 (ja, da musst du eine entsprechende Variable anlegen, damit das darin gespeichert werden kann), sagen wir mal MySock : TCustomWinSock;
In der Form2 kannst du dann mit MySock.SendText() die Nachricht schicken!

Der Code in der DATA.pas sieht grauenvoll aus.

Du erzeugst eine TForm2 (Zeile 43) und dann erzeugst du wieder eine TForm2 (Zeile 56) und die übergibst du dann???
Die erste Form wird angezeigt (Zeile 59) die zweite Form bleibt im Nirwana.

Form1.Counter wird gesetzt (Zeile 56) und dann nochmal einen hochgezählt (Zeile 61) ist aber für nix gut!

Über das Form1.StringGrid1 holst du dir die Anzahl und hoffst, dass das auch mit FormList passt ( Zeile 65-68 )!

Es ist alles sehr konfus ...

Also mach TForm2 als Klasse mit einem Memo1 und einem MySocket : TCustomWinSocket.
Das Form1.StringGrid1 kannst du eigentlich vergessen (oder wenn du magst als Anzeige für den Inhalt vom FormList nehmen).

Die Überprüfung kannst du dann wie folgt machen (FormList gehört in DATA.pas und nicht nach Form1)
Delphi-Quellcode:
for
  i := 0 to
  FormList.Count - 1 
do
  if
    Socket.RemoteAddress = TForm2( FormList[ i ] ).MySocket.RemoteAddress
  then
    TForm2( FormList[ i ] ).Memo1.Lines.Add( Socket.ReceiveText );

Sir Rufo 8. Dez 2008 15:04

Re: Problem mit Programminternem Chat
 
Ich glaube du schaust am besten mal hier nach


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