Design Client<->Server Kommunikation



  • Hallo!

    Ich weiß, daß dies nicht direkt mit dem BCB zu tun hat, aber vielleicht könnt Ihr mir ja ein paar Anregungen geben.

    Ich schreibe zur Zeit eine Art serverbasierten Chat mit dem BCB 6.0. Clients und Server nutzen einen festgelegten Port. Die Kommunikation findet über Sockets und SendText() und ReceiveText() statt.

    Im Client habe ich u.a. zwei TreeViews, innerhalb derer einerseits die User, andererseits die Räume dargestellt sind. Die Nodes werden jeweils aufgrund
    einer Steuermeldung des Servers on the fly erzeugt, die Nodes bekommen je nach Status des jeweiligen Users ein entsprechendes IndexImage etc. pp. Ebenso werden eine ganze Reihe von weiteren Aktionen in den Clients durch Steueranweisungen des Servers angestossen.

    Zur Zeit findet diese Kommunikation über Sequencen statt, welche ich im Server und in den Clients filtere. Als Format benutze ich "000000|Parameter". Ich prüfe also jede Nachricht auf den Delimiter und habe dann meine Steuercodes, also z.B. 100000|MyName = Erzeuge neuen Node mit Text MyName.

    Daß ein User einen solchen Steuercode nicht selbst eingeben kann, stelle ich sicher, in dem ich "|" als Eingabe nicht zulasse. Die übermittelten Nachrichten werden verschlüsselt. Das alles funktioniert zur Zeit ganz gut.

    Was mir im Augenblick ein wenig Kopfzerbrechen macht ist, ob dieser Weg mit den Steuersequencen vernünftig ist, oder ob es bessere Wege gibt, dies zu implementieren. Habt Ihr irgendwelche Ideen, oder so etwas schon einmal gemacht? Und wie?

    Gruss

    Ralf-J.



  • hm
    wenn du schon so fragst...

    Ich find dafür WebService gut geeignet

    http://www.drbob42.com/soap/soap42.htm

    oder:

    siehe http://www.ebob42.com/cgi-bin/soap42.exe?Server=C&Web=E&DB=C&Client=C

    oder such mal in Google nach BCB, SOAP WebService, WebSnap, WebBroker usw.



  • wie funktioniert eigentlich WebService? u wo hat das vorteile bzw nachteile?
    wer hat schon mal was damit in c++ implementiert?

    cu



  • Hallo,

    Je komplexer ein Programm wird, desto ungeeigneter wird eine Soket-Implementierung. Genau dieses hast du jetzt wahrscheinlich festgestellt.
    Als mir diese Tatsache bewusst wurde, habe ich mich ausgiebig nur mit Middleware beschäftigt.

    Das Thema ist aber zu Komplex um das nun in ein Beitrag packen zu können. Deshalb nur mal so ein Überblick:

    Ein Webservice ist vom Prinzip her ist eine Webanwendung. Daher wird Webservice meist auch über http betrieben (es geht auch über TCP). Die Kommunikation ist ein reines Frage-Antwortspiel auf XML-Basis. Es können Klassen für die Kommunikation genutzt werden und ein Client kann Methoden einer Klasse auf den Server aufrufen. Dafür müssen beide aber wissen, wie sie die Klassen über XML verschicken müssen. Das wird in einer WSDL-Datei festgelegt.

    Was jeder auch einmal gemacht haben sollte ist ein Programm mit CORBA

    Hier ein CORBA-Tutorial

    Das Prinzip ist ähnlich wie das vom Webservice. Eine Datei definiert wiederum das Format der Klassen und kommuniziert wir über diese Klassen. Allerdings meist über TCP.
    Beim WebService übernimmt in der Regel ein Webserver die Steuerung. Bei Corba ist das ein ORB = ObjektRequestBroker.

    Allerdings ist CORBA weitaus komplexer. Zum Beispiel ist es in CORBA möglich eine eventgesteuerte Kommunikation über callbacks umzusetzen.
    Auch können Corba-Server geclustert werden. Wobei auch eine Dynamische Clusterung möglich ist. Zum beispiel wird vom ORB einfach auf ein Rechner ein Corba-Server gestartet, wenn das Loadbalancing das erfordert oder die angeforderten Daten eine Instanzierung dieses Servers erfordert, weil zum Beispiel ein anderer Server diese Daten nicht liefert.Ein sehr komplexes Thema.

    Für beide Varianten gibt es libs, die aus Klassen entsprechende FOrmatdateien erzeugen (WSDL,IDL).

    Vorteile von Webservice gegenüber CORBA

    - Einfacher zu handeln
    - XML ist leicht umzusetzen und zu lesen.
    Nachteile:
    - eine Umsetzung von Klassen in XML erzeugt ein Stringstream,der, je nach Komplexität der Klasse, ungefähr 7-20 mal so groß ist, wie der Binärstream der Klasse. Das liegt daran, dass alles in Text umgewandelt wird und zur Identifizierung der Klassen noch entsprechende XML-Tags eingebaut werden. Bei großen Datenmengen kann das zu ein Problem werden.Nicht nur wegen der Konvertierung in den Stringstream sondern auch die Datenübertragung dauert dann. Mann kann die DAten dann packen, allerdings kostet das auch wieder Zeit.

    Vorteile von CORBA gegenüber Webservice
    - Mächtiger
    - Statusvoll- es können Singelton- Objekte erzeugt werden. Das geht mit Webservice nicht (zumindest nicht direkt).
    - Callbacks Möglich
    - Clustering Möglich
    - Schneller - da keine Textkonvertierung
    - Binär-Übertragung ist ebenfalls besser, da der Datenstrom nicht so groß ist

    Vorteile von Webservice und Corba gegenüber einer Soket-Implementierung:

    - Typisierte Kommunikation
    - Plattform- und Sprachunabhängig
    - Keine Mehrfachbindung von Ports, da alles über ein Port abgewickelt wird.
    - Threadsicher (Bei SingleTon-Objekten mit CORBA muss man glaub ich ein wenig aufpassen. Bin mir da nicht ganz sicher.)
    Nachteile:
    - es ist eine gewisse Einarbeitung notwendig.

    Übrigens ist das Parsen von Klassen kein zusätzlicher Aufwand.Schließlich müsste amn ja auch in der Soket-Variante in ein BinärStream parsen.
    Für Webservice und CORBA gibs da entsprechende libs, die das Parsen erleichtern bis automatisieren.

    Beispiele wirst du im Internet genug finden können.

    Wenn du konkretere Fragen hast, kannst du diese ja hier stellen. Für ein Beispiel habe ich aber keine Zeit.



  • Hi,

    hab in den letzten Wochen auch einen umfangreichen Chat programmiert und ich hab das mit SubString gemacht. Ich schicke z.B.: ####UserLogin#Username# und überprüfe dann ob #### empfangen wurde. Dann lese ich den Befehl bis zum nächsten # aus (for) und überprüfe diesen dann mit einer if Abfrage. Würde dann mit einer weiteren for Schleife den Usernamen auslesen und diesen speichern.
    Aber wie hast du das denn mit der Verschlüsselung gemacht? Ich mein ich hab auch eine aber wenn ich Sie aktiviere und in kurzer Zeit viel Text gesendet wird kommt ne dicke Fehlermeldung. Frag mich nur nicht warum.

    Decode=new char[Buff.Length()];
    strcpy(Decode,Buff.c_str());
    for(unsigned int i=Standard,j=0;j<strlen(Decode);j++,i=Standard)
                 {
                  Decode[j]=((byte)Decode[j])-i++;
                 }
    Buff=Decode;
    delete[] Decode;
    

    Mein Problem ist aber auch die Sache mit den Threads. Hab mich damit noch nicht beschäftigt aber wenn der Chat für viel User sein soll ist das wohl zwingend notwendig. Benutzt du denn Threads?

    Sebastian



  • Normalerweise sind für ein Chat keine Threads notwendig.

    Gründe für Threads liegen eigentlich nur vor, wenn du
    1. Eine Trennung zwischen Anmeldung und Chaten haben möchtest
    2. Mehrere Chat-Räume verwalten willst.

    Ein Thread-Tutorial findest du im BCB-Tutorial.(Siehe Signatur)

    Wenn du uns dann noch die Fehlermeldung verraten würdest, müsste wir nicht raten oder junix bitten, seine Kristallkugel zu holen.



  • Also könnte ich, wenn ich z.B. nur einen Chat-Raum habe, mit sagen wir mal 10 Client's kommunizieren ohne einen Thread zu benutzen? Wie ist das denn wenn jetzt Client A und B zur gleichen Zeit ihre Nachrichten abschicken? Kann das Programm dann nicht crashen? Muss doch eigentlich, weil wenn der Text von Client A noch entschlüsselt wird oder durch eine ander Funktion läuft, kann das Programm doch nicht bereits die nächste Nachricht empfangen?!? Oder kommt diese dann erst gar nicht an?

    Zu meiner Fehlermeldung, wäre schön wenn es nur eine wäre:

    Beim Client:

    Die Anweisung in "0x410046de" verweist auf Speicher in "0x0045d344". Der
    Vorgang "written" konnte nicht auf dem Speicher durchgeführt werden.

    Die Ausnahme "unknown software exception"(0x0000027) ist in der Anwendung
    an der stelle 0x77e748b0 aufgetreten.

    das Client Programm schließt sich danach. Dann kommt etwas ähnliches beim Server (nur mit anderen Adressen) gefolgt von einem:

    Asynchroner Socket-Fehler 10053

    und der

    Abnormal program termination

    dann ist auch der Server "weg".

    Mir sagt das leider nicht besonders viel. Fehlersuche lernt man an meiner Schule leider nicht 😉 hab leider gerade erst angefangen mich mit dem Debugger auseinander zu setzen.



  • Daß ein User einen solchen Steuercode nicht selbst eingeben kann, stelle ich sicher, in dem ich "|" als Eingabe nicht zulasse. Die übermittelten Nachrichten werden verschlüsselt. Das alles funktioniert zur Zeit ganz gut.

    Wäre es nicht besser zu senden "Jetzt kommt eine Nachricht, sie ist xxx Bytes lang" und interpretiert die nächsten xxx Bytes als Nachricht?


Anmelden zum Antworten