AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Chat mit PM

Ein Thema von hans ditter · begonnen am 3. Okt 2010 · letzter Beitrag vom 10. Okt 2010
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Chat mit PM

  Alt 8. Okt 2010, 14:20
Den Link wo man JSON für Delphi bekommt habe ich hier schon gepostet (s. in den oberen Threads)
o := SO; erzeugt mir ein leeres JSON-Object, mit dem ich ab jetzt arbeiten kann.
Jetzt möchte ich diesem JSON-Object für die Eigenschaft 'CMD' den String-Wert 'MSG' übergeben.
Das schöne bei JSON-Objekte ist, die Eigenschaft wird automatisch angelegt, wenn diese noch nicht existiert.
also
o.S[ 'CMD' ] := 'MSG'; Wenn ich einen Integer-Wert übergeben möchte schreibe ich einfach
o.I[ 'Wert' ] := 10; Auslesen geht genauso einfach
if o.S[ 'CMD' ] = 'MSGthen Unter dem Link findest du auch ein Forum sowie eine kurze Anleitung.

Stell dir das JSON erstmal so vor: Da kann ich sehr einfach was reinschmeissen und wieder auslesen und das gesamte bekomme ich als Text ShowMessage( o.AsJSON ); geliefert und kann das sonstwohin schieben (z.B. als Nachricht über den Socket).

Das JSON-Objekt ist dabei nur Hilfsmittel, weil du dich um das korrekte Verpacken und Trennen der einzelnen Teile nicht selber kümmern musst. Du brauchst es nur benutzen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Chat mit PM

  Alt 8. Okt 2010, 20:56
Hey, super das du doch geantwortet hast... ich hatte schon befürchtet, ich hab jetzt alle abgeschreckt...
Das hört sich doch super an... damit sind meine größten Probleme schonmal geklärt... DANKE!!
Aber ich habe da noch immer ein Problem bei der Serverabfrage (wobie diese eher auf dem Verständnis des Vorgangs beruht):
Delphi-Quellcode:
o.I[ 'COUNT' ] := 0;
        // Senden
        for idx := 0 to TServerWinSocket( Sender ).ActiveConnections - 1 do
          // an alle?
          if ( ( o.[ 'TO' ] = '' ) or
            // an diesen Benutzer?
            ( o.S[ 'TO' ] = <Deine Userabfrage> ) ) and
            // nicht an den Client der gerade sendet
            ( Socket <> TServerWinSocket( Sender ).Connections[ idx ] ) then
            begin
              TServerWinSocket( Sender ).Connections[ idx ].SendText( o.AsJSON );
              o.I[ 'COUNT' ] := o.I[ 'COUNT' ] + 1;
            end;
         // Und wieder zurück an den Client
         Socket.SendText( o.AsJSON );
      end;
Was passiert in diesem Abschnitt?
1.) Ich kann dem ganzen soweit folgen, dass ein Integerwert 'Count' angelegt wird und mit null gefüllt ist. Aber wofür brauchst du diesen Integerwert??
2.) Warum fragst du ab, ob an alle oder nur an eine Person und nicht an den sendenden Clienten geschickt werden soll? Denn nach dem then schickst du die Nachricht doch sowieso wieder an alle (mit der for-Schleife).
Der Rest ist mir im Moment noch ziemlich klar... mal schauen, vlt ergeben sich da ja auch noch Probleme.

Dann hätte ich zu dem JSON-Quellcode noch eine Frage. Ich hab leider nur Turbo Delphi... ist das richtig, dass dies nichtmal eine Komponente ist, die man installieren kann? Sondern die man nur im uses-Bereich einfügen muss? Ich bin davon mal ausgegangen, aber in welchen Ordner muss ich dann die superobject.pas Datei speichern? Ich dachte mir unter C:/Programme/Borland/BDS/source ... aber wo dann hin? Ich hab da die Ordner dUnit, Indy10, IntraWeb, ToolsAPI und Win32 anzubieten...

Ich freue mich schon auf deine nächste Antwort,
hans ditter

p.s.: Natürlich auch an alle anderen ein großes Dank, die sich hier beteiligt haben, um mir zu helfen. Vor allem natürlich xZise.
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Chat mit PM

  Alt 8. Okt 2010, 22:12
Ok, das mit dem COUNT ist eigentlich nur Spielerei ... damit wollte ich dem sendenden Client zurückmelden, an wieviele Clients die Nachricht geschickt wurde. Ist also erstmal überflüssig
Delphi-Quellcode:
{...}
        // Senden

        // Wir werden jetzt alle Verbindungen prüfen, ob wir denen was senden müssen
        // dazu finden wir in TServerWinSocket( Sender ).ActiveConnections die Anzahl der aktiven Verbindungen

        for idx := 0 to TServerWinSocket( Sender ).ActiveConnections - 1 do
          begin // Das begin und end ist nicht notwendig, dient nur der Übersichtlichkeit

            // ist TO leer, dann wird wird die Nachricht an alle geschickt

            if ( ( o.[ 'TO' ] = '' ) or

              // oder steht da was drin, dann geht es nur an diesen Benutzer
              // die Userabfrage muss jetzt den Benutzer zu dem Socket aus
              // TServerWinSocket( Sender ).Connections[ idx ]
              // liefern also irgendwie sowas
              // function GetUserNameFromSocket( Socket : TCustomWinSocket ) : string

              ( o.S[ 'TO' ] = GetUserFromSocket( TServerWinSocket( Sender ).Connections[ idx ] ) ) ) and

              // aber es soll nicht an die Verbindung geschickt werden, die die Nachricht abgeschickt hat

              ( Socket <> TServerWinSocket( Sender ).Connections[ idx ] ) then
              begin

                TServerWinSocket( Sender ).Connections[ idx ].SendText( o.AsJSON );

              end;

          end; { --- hier endet die for-Schleife --- }

        // Wir schicken dem Absender die Nachricht wieder zurück, damit der weiß, dass wir alles erledigt haben

        // Damit der Client weiß, dass es sich um eine Rückantwort handelt schreiben wir noch etwas in die Nachricht

        o.S[ 'SEND' ] := 'OK';

        // und auf die Reise schicken

        Socket.SendText( o.AsJSON );
     end;
Ja, es wird einfach nur die unit superobject eingebunden. Da braucht (gottseidank) nichts installiert werden.

Wenn du diese Unit nur in deinem Projekt nutzen möchtest, dann kann st du die datei "superobject.pas" einfach in dein Projekt-Ordner kopieren.
Willst du immer wieder auf diese Unit zurückgreifen, dann sollte die Datei in einem Ordner stehen, der laut Bibliothekspfad auch eingebunden wird. Schau einfach in deiner IDE unter "Tools->Optionen->Bibliothek - Win32->Bibliothekspfad->[...]
Mit einem Klick auf den Button mit den drei Punkten (nein, der ist nicht gelb ) kannst du auch weitere Pfade hinzufügen.

Bei mir sind die unter "%PUBLIC%\Dokumente\superobject" gespeichert und dann habe ich den Pfad zur Bibliothek hinzugefügt.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Chat mit PM

  Alt 8. Okt 2010, 22:54
Ok, cool!! Ich hab das aber mit dem User herausfinden noch nicht ganz gerafft.
Mein Delphi kennt beim Server die Funktion GetUserFromSocket nicht. Was mache ich falsch bzw. wie komme ich dann an die Verbindung ran?
Auch finde ich im Moment "TServerWinSocket" nicht ... ich habe die ganze Weiterleitung etc. in OnClientRead (ist das korrekt?), da gibt es aber nur ...ClientRead(Sender: TObjet; Socket: T[B]Custom[/B]WinSocket); .
Und:  ( Socket <> TServerWinSocket( Sender ).Connections[ idx ] ) then --> ist Socket nicht gleich TServerWinSocket??

Ich bin noch etwas auf Kriegsfuß mit der internen Verbindungsliste des TServerSocket... hast du vlt schon bemerkt... Vlt kannst du mir da nochmal etwas auf die Sprünge helfen... DANKE!!

LG, hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!

Geändert von hans ditter ( 8. Okt 2010 um 23:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#5

AW: Chat mit PM

  Alt 8. Okt 2010, 23:19
Ok, cool!! Ich hab das aber mit dem User herausfinden noch nicht ganz gerafft.
Mein Delphi kennt beim Server die Funktion GetUserFromSocket nicht.[...]
Die Funktion musst du dir auch noch schreiben. Damit findest du den Nickname zu einer Verbindung heraus. Das heißt irgendwo musst du speichern, wie der Nickname einer bestimmten Verbindung lautet.
Am besten ginge das wohl mit einer DictionaryDictionary. Zum Beispiel einer HashlistHashlist.

MfG
Fabian
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: Chat mit PM

  Alt 8. Okt 2010, 23:23
Die Funktion musst du dir auch noch schreiben. Damit findest du den Nickname zu einer Verbindung heraus. Das heißt irgendwo musst du speichern, wie der Nickname einer bestimmten Verbindung lautet.
Am besten ginge das wohl mit einer DictionaryDictionary. Zum Beispiel einer HashlistHashlist.
Äääääääähm. . . ???? Was?? Ist das sowas, was ich schonmal machen wollte? Mit einer Liste, die IP, UserNick und Pointer auf das Socket speichert? Oder ist das noch wieder was anderes? Wenn ja, könntest du dann mal ein Beispielcode posten?
Danke!

lg, hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Chat mit PM

  Alt 8. Okt 2010, 23:56
Das ist im Grunde genommen diese Liste. Ich sagte auch "am besten ginge es ...", aber da müsste ich noch mehr erklären und man müsste sich das erst downloaden/zusammensuchen.

Ich würde dir empfehlen: Du speicherst in einer Liste zu welcher Connection, welcher Benutzername gehört. Das heißt erstmal findest du heraus, welcher Datentyp .Connections[ idx ] ist. Und dann machst du das entweder mit Records oder mit Klassen und speicherst zu jeder Verbindung, welcher Benutzername dazu gehört.

Das speicherst du in die Liste und die dir unbekannte Methode geht dann einfach die Liste durch und sucht den Benutzername.
So ungefähr könnte man das machen:
Delphi-Quellcode:
type
  PElement = ^TElement;
  TElement = record
    Nick : string;
    Connection : TConnection; // Den Datentyp von oben! Ich weiß es gerade nicht, also einfach mal gucken!
  end;

  TConnections = class(TObject)
  private
    FConnections : TList; // Im Konstruktor erstellen/Destruktor freigeben
  public
    procedure AddConnection(Nick : string; Connection : TConnection);
    procedure RemoveConnection(Nick : string);
    function GetUserFromSocket(Connection : TConnection) : string; // Das ist einfach durchgehen und testen
  end;


procedure TConnections.AddConnection(Nick : string; Connection : TConnection);
var
  e : PElement;
begin
  New(e);
  e.Nick := Nick;
  e.Connection := Connection;
  FConnections.Add(e);
end;

procedure TConnections.RemoveConnection(Nick : string);
var
  e : PElement;
begin
  // Nick suchen
  for i := 0 to FConnections.Count - 1 do
  begin
    e := PElement(FConnections[i]);
    if (e.Nick = Nick) then
    begin
      FConnections.Delete(i);
      Dispose(e);
      Exit;
    end;
  end;
end;
Alle Angaben ohne Gewähr!

MfG
Fabian

PS: Die Dictionary wäre halt schneller, aber so gehts auch erstmal.
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Chat mit PM

  Alt 9. Okt 2010, 01:04
Ok, cool!! Ich hab das aber mit dem User herausfinden noch nicht ganz gerafft.
Mein Delphi kennt beim Server die Funktion GetUserFromSocket nicht. Was mache ich falsch bzw. wie komme ich dann an die Verbindung ran?
Wie xZise schreibt, die musst du selber erstellen ... ich bin aber (nach dem was du hier geschrieben hast) davon ausgegangen, dass du schon so eine Liste führst (User,Socket). Die Funktion sucht dann aus der Liste den Socket und liefert den User.

Auch finde ich im Moment "TServerWinSocket" nicht ... ich habe die ganze Weiterleitung etc. in OnClientRead (ist das korrekt?), da gibt es aber nur ...ClientRead(Sender: TObjet; Socket: T[B]Custom[/B]WinSocket); .
Und:  ( Socket <> TServerWinSocket( Sender ).Connections[ idx ] ) then --> ist Socket nicht gleich TServerWinSocket??
Du hast doch eine TServerSocket-Komponente auf deiner Form liegen. Ich weiß nicht wie die heißt ... ist aber auch egal.
Nehmen wir mal an, die heißt ServerSocket1, dann hätte ich auch schreiben können ServerSocket1.Connections[ idx ] aber sowas ist immer doof, denn wenn du die Komponente umbenennst, dann funktioniert dein Code nicht mehr.
In dem Parameter Sender habe ich den Verweis auf die Komponente die diese Methode aufruft, und das ist deine TServerSocket (wie immer die auch heißen mag). Durch die Vererbung (OOP) brauche ich die Sicht auf TServerWinSocket (davon ist TServerSocket abgeleitet), denn ab da kann ich auf die Connections zugreifen.
Sender ist aber erst mal vom Typ TObject (siehst du an der Definition der Methode procedure ClientRead(Sender: TObject; Socket: TCustomWinSocket); ). Darum benötige ich/du einen TypeCast und den macht man mit TServerWinSocket( Sender ) . Jetzt kannst du deine Komponente auch in RudiRüsselSeineSocketKomponente umbenennen und es (diese Methode) wird immer noch funktionieren (in D2010 kann man auch ein ü im Namen haben).

Ich hätte auch TServerSocket( Sender ) nehmen können, es ist aber besser immer die niedrigste benötigte Ableitung im TypeCast zu verwenden. Das wirst du merken, wenn du mal etwas mehr mit OOP arbeitest

Soweit zum TypeCast

( Socket <> TServerWinSocket( Sender ).Connections[ idx ] ) Hier die Bedeutung der einzelnen Elemente:

Socket -> Verbindung zum Client, von dem aktuell die Nachricht empfangen wird
TServerWinSocket( Sender ).Connections -> Liste mit allen Verbindungen zum Server
TServerWinSocket( Sender ).Connections[ idx ] -> Verbindung zu einem Client

Innerhalb der for-Schleife (idx) prüfe ich, ob die Verbindung[ idx ] = der Verbindung des Clients ist von dem aktuell die Nachricht empfangen wird, weil dem will ich die Nachricht ja nicht mehr schicken.
Der bekommt im Anschluss zwar auch eine Nachricht, aber mit einer anderen Intention.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 9. Okt 2010 um 09:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#9

AW: Chat mit PM

  Alt 9. Okt 2010, 09:33
Moin,
könnte er sich dann nicht den Cast sparen und einfach den zweiten Parameter verwenden?

MfG
Fabian
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Chat mit PM

  Alt 9. Okt 2010, 09:42
Moin,
könnte er sich dann nicht den Cast sparen und einfach den zweiten Parameter verwenden?

MfG
Fabian
Nein (ok ich hatte mich im letzten teil vertippt, hab es aber jetzt korrigiert), denn ich brauche ja den Zugriff auf den ServerSocket um alle anderen Verbindungen (Sockets) zu erfahren
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 03:40 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