[DE] Wie reagiert eigentlich Zyan bei.... (solved)

Topics: Technical Support
Mar 1, 2011 at 9:29 PM

1. Einer Methode die gerade am laufen ist und der Server wird gestoppt... bsp FileTransfer...

Wie fange ich sowas am besten ab, muss ich da jede Methode die ich aufrufe mit Try catch ummanteln oder hast du da eine bessere Lösung?

Wie erfährt der Client am besten wenn der Server weg ist oder sich herunterfährt?

Was sind Best practices für diese Implementierung?

---

Noch eine Frage, kannst du mir ein bsp. geben für Clientcalled Objekten in Verbindung mit Serverside Objekten also beides in einem Programm über den gleichen Port?

Dies möchte ich wissen weil ich gerne high performante Funktionen nutzen möchte jedoch nur einen Port nutzen will. Der Server jedoch soll State Objekte haben um über den Stand der Clients informiert zu bleiben.

---

Hast du dir auch schonmal überlegt wie man per Remote mit sehr grossen Datenbanken arbeitet?

Datasets sind unter Umständen zu gross, ich dachte da eher an Serverseitigige Verarbeitung und der Client requested immer beim Scrollen neue Einträge an...

Hast du da ev. eine bessere Idee? Das DataGrid  würde ich dann per Virtual Mode nutzen.

Ich weiss das hat nicht viel mit Zyan zu tun, aber ich dachte ich frage einfach.

---

Vielen Dank für Zyan :) Es ist wirklich sehr hilfreich.

Coordinator
Mar 1, 2011 at 11:01 PM
Edited Mar 1, 2011 at 11:09 PM

Hallo blackdog,

> Einer Methode die gerade am laufen ist und der Server wird gestoppt... bsp FileTransfer...

Wenn der Arbeitsthread auf dem Server durch z.B. das Stoppen des Windows-Dienstes, der als Server-Prozess fungiert, abgebrochen wird, wird der Client eine Ausnahme bekommen. Das wird wohl entweder eine RemotingException oder eine TargetInvocationException sein. Wenn der Netzwerkstecker herausgezogen wird, kriegt der Client eine SocketException.

> Was sind Best practices für diese Implementierung?

Auf der Serverseite ist wenig zu befürchten (z.B. wenn bei einem Callback oder einem Event ein Fehler auftritt). Wenn es da knallt, schmiert der betroffene Arbeitsthread ab. Andere Threads beinflusst das nicht. Wenn nicht gerade die Netzwerkhardware des Servers offline geht und ihre IP Adresse verliert, sollte der Server weiterlaufen.

Clientseitig hilft Stand Zyan Version 1.2 nur try/catch. Das wird sich mit Zyan 2.0 ändern. Da wird die ZyanConnection ein eigenes Ereignis zur Behandlung von Verbindungsproblemen haben. Das Verhalten kann dann bequem an zentraler Stelle gesteuert werden. Es könnte z.B. eine bestimmte Zeit lang versucht werden, den Vorgang zu wiederholen. Serverseitig wird es in Zyan 2.0 die Möglichkeit geben, den ZyanComponentHost anzuweisen, keine weiteren Anfragen anzunehmen, aber die bereits begonnenen abzuarbeiten. Beim Stoppen des Server-Dienstes (falls man z.B. den Server als Windows-Dienst implementiert hat, was häufig der Fall ist) könnte man noch eine bestimmte Zeit lang warten, bis die aktuellen Anfragen fertig verarbeitet sind.

Version 2.0 wird aber noch etwas dauern, da der neue DuplexChannel noch nicht in allen Situationen so will, wie ich mir das vorstelle.

> Noch eine Frage, kannst du mir ein bsp. geben für Clientcalled Objekten in Verbindung mit Serverside Objekten also beides in einem Programm über den gleichen Port?

Sorry, das habe ich nicht ganz verstanden. Was sind Clientcalled Objekte? Kannst Du das bitte etwas näher beschreiben?

> Hast du dir auch schonmal überlegt wie man per Remote mit sehr grossen Datenbanken arbeitet?

Ich arbeite oft mit sehr großen Datenbanken (wenn für Dich Datenbanken jenseits der 25 GB als groß gelten).

> Datasets sind unter Umständen zu gross, ich dachte da eher an Serverseitigige Verarbeitung und der Client requested immer beim Scrollen neue Einträge an...

Da muss ich wiedersprechen. Ich arbeite fast ausschließlich mit DataSets. Warum sollten die zu groß sein? Es wird immer nur das übertragen, was auch an Daten in ein DataSet reingeladen ist. Wenn ich 20 Adressen in ein DataSet lade, ist das das nicht mehr, als wenn ich die 20 Adressen in eine List<Address> übertrage. Beim DataSet kann ich sogar auf Wunsch nur die Änderungen übertragen (GetChanges-Methode), da DataSets im Vergleich zu Standardobjekten einen RowState haben.

Ich vermute, dass Du DataSets bisher noch nicht optimal eingesetzt hast, bzw. noch nicht alle Möglichkeiten kennst. DataSets unterstützen auch nachladen und zusammführen von Daten (Merge-Methode). Damit lässt sich auch im Virtual Mode mit dem DataGridView arbeiten. Du könntest einen Hintergrundthread auf dem Client haben, der sich um das Nachladen der Daten ins lokale DataSet kümmert. Natürlich kannst Du das auch ganz ohne DataSets machen. Das ist eine Frage der persönlichen Vorliebe. Du solltest auf jeden Fall immer ganze Blöcke (z.B. 100 Datensätze) am Stück abrufen und nicht jeden einzelnen Datensatz beim scrollen vom Applikationsserver nachladen. Sonst hast Du sehr viel Netzwerkoverhead.

Gruß Hagen

Mar 2, 2011 at 7:04 AM

> Version 2.0 wird aber noch etwas dauern, da der neue DuplexChannel noch nicht in allen Situationen so will, wie ich mir das vorstelle.

Das ist ok, lieber länger dafür funktioniert es auch :)

> Sorry, das habe ich nicht ganz verstanden. Was sind Clientcalled Objekte? Kannst Du das bitte etwas näher beschreiben?

Singleton- and SingleCall,  ich habe mich glaub ein bisschen unklar ausgedrückt. Kann man mit Zyan diese 2 Mischen auf dem gleichen Port? Beim Remote Helper war dies ja nicht der Fall, den ich bis anhin benutzt habe :)

> Ich arbeite oft mit sehr großen Datenbanken (wenn für Dich Datenbanken jenseits der 25 GB als groß gelten).

Das ist mittelgross, aber ja es kommt ja nicht nur auf die Grösse an, sondern auf die verarbeitung der Nutzdaten.

>Da muss ich wiedersprechen. Ich arbeite fast ausschließlich mit DataSets. Warum sollten die zu groß sein? Es wird immer nur das übertragen, was auch an Daten in ein DataSet reingeladen ist. Wenn ich 20 Adressen in ein DataSet lade, ist das das nicht mehr, als wenn ich die 20 Adressen in eine List<Address> übertrage. Beim DataSet kann ich sogar auf Wunsch nur die Änderungen übertragen (GetChanges-Methode), da DataSets im Vergleich zu Standardobjekten einen RowState haben.

Hmm intressant. Also lädst du die Datasets als Referenz oder als return wert? Ich seh schon ich muss noch viel über Datasets lernen :) Was ich letzte erst gelesen hab ist, das ein Dataset gezwungen werden muss Binär übertragen zu werden da es Standardmässig als XMl übertragen wird. Dies macht ein riesen Unterschied.

> Ich vermute, dass Du DataSets bisher noch nicht optimal eingesetzt hast, bzw. noch nicht alle Möglichkeiten kennst. DataSets unterstützen auch nachladen und zusammführen von Daten (Merge-Methode). Damit lässt sich auch im Virtual Mode mit dem DataGridView arbeiten. Du könntest einen Hintergrundthread auf dem Client haben, der sich um das Nachladen der Daten ins lokale DataSet kümmert. Natürlich kannst Du das auch ganz ohne DataSets machen. Das ist eine Frage der persönlichen Vorliebe. Du solltest auf jeden Fall immer ganze Blöcke (z.B. 100 Datensätze) am Stück abrufen und nicht jeden einzelnen Datensatz beim scrollen vom Applikationsserver nachladen. Sonst hast Du sehr viel Netzwerkoverhead.

Richtig geraten. Ich hab noch wenig mit Remote gemacht, möchte aber so weit es geht ein Datenbank Framework errichten für Oracle und MSSQL.

Es soll möglich sein, so wies aussieht nun über Datasets Netzwerkschonende Datenübertragung zu gewähren, das der Client das Resultat sofort verarbeiten kann.

Ich kämpfe gerade mit der Art, wie ich das implementieren soll.

Das Problem was ich meinte ist, in einer Anwendung die ich entwicklen möchte soll es möglich sein eine Länger dauernde Suche zu cachen.

Beispiel: Die Suche dauert 5 Minuten ich erhalte damit 100 000 Records, mit etwa 20 Spalten. Separiert noch Blobs, auf die ich Momentan nicht gross eingehe.

Mein Problem hierbei ist ohne das ich den Server erneut mit der Suche belästigen möchte, wie kann ich dem Client die Möglichkeit geben ohne dass ich die ganzen 100 000 Records schicke, dies vernünftig und Netzwerk traffic schonend zu übertragen.

Würdest du da das DataSet Serverseitig behalten und dem Client Chunk weise schicken? Was ist wenn das 100te von Clients machen, das geht doch sehr auf das Memory, soweit ich weiss ist das Dataset nur im Memory.

---

Gibt es den eine Möglichkeit im Zyan ohne Wireshark oder dergleichen zu sehen wieviel wirklich über die Leitung geht, also wie gross die Daten nicht im Memory sondern über die Leitung sind, ich denke das wäre nützlich um zu sehen ob eine Anwendung Netzwerk schonend arbeitet. Bsp. Call 100KB Received 1 MB Sent..

---

Danke für die Antworten

Coordinator
Mar 2, 2011 at 8:58 PM

> Singleton- and SingleCall,  ich habe mich glaub ein bisschen unklar ausgedrückt. Kann man mit Zyan diese 2 Mischen auf dem gleichen Port? Beim Remote Helper war dies ja nicht der Fall, den ich bis anhin benutzt habe :)

Ja, kann man mischen. Du kannst die Aktivierungsart (SingleCall/Singleton) beim registrieren der Komponenten (ZyanComponentHost.RegisterComponent bzw. ComponentCatalog.RegisterComponent) angeben.

> Hmm intressant. Also lädst du die Datasets als Referenz oder als return wert?

Das macht bei Remoting keinen Unterschied. In beiden Fällen wird das DataSet serialisiert. Ich verwende Merge, um vom Server abgerufene Daten mit den lokalen bereits geladenen Daten zusammenzuführen. Diese Methode verträgt sich am besten mit Databinding.

> Was ich letzte erst gelesen hab ist, das ein Dataset gezwungen werden muss Binär übertragen zu werden da es Standardmässig als XML übertragen wird. Dies macht ein riesen Unterschied.

Ja, Du musst die Eigenschaft RemotingFormat auf Binary einstellen.

> Das Problem was ich meinte ist, in einer Anwendung die ich entwicklen möchte soll es möglich sein eine Länger dauernde Suche zu cachen.

Cachen solltest Du der Datenbank überlassen. Die macht das mit ziemlicher Sicherheit viel effizienter. Vor allem müsstest Du dafür serverseitig statuswahrend arbeiten. Das ist tödlich für die Skalierbarkeit Deiner Anwendung. Der Server sollte statuslos sein.

> Würdest du da das DataSet Serverseitig behalten und dem Client Chunk weise schicken? Was ist wenn das 100te von Clients machen, das geht doch sehr auf das Memory, soweit ich weiss ist das Dataset nur im Memory.

Nein, auf keinen Fall. Ich würde das Paging auf die Datenbank abwälzen (z.B. so http://www.sqlteam.com/article/server-side-paging-using-sql-server-2005). Wenn Du im DataGridView scrollst, lädst Du bei Bedarf weitere Datensätze nach, indem Du eine Anfrage an den Applikationsserver stellst. Die Serverkomponente sendet den SQL Paging-SELECT an die Datenbank und bekommt die nachzuladenden Daten zurück. Diese werden dann als DataSet/DataTable an den Client zurückgesendet und per Merge ins lokale DataSet des Client eingefügt.

> Gibt es den eine Möglichkeit im Zyan ohne Wireshark oder dergleichen zu sehen wieviel wirklich über die Leitung geht, also wie gross die Daten nicht im Memory sondern über die Leitung sind, ich denke das wäre nützlich um zu sehen ob eine Anwendung Netzwerk schonend arbeitet. Bsp. Call 100KB Received 1 MB Sent..

Ja das geht. Allerdings musst Du Zyan dafür etwas erweitern. Du musst eine Remoting Kanalsenke schreiben. Diese kannst Du in die Remoting-Infrastruktur einhängen und bekommst Du direkten Zugriff auf den NetworkStream unter der Haube und kannst jedes einzelne Byte zählen, das übers Kabel geht. Du brauchst aber ein gewisses Maß an Hintergrundwissen über die Architektur con .NET Remoting (die Zyan intern verwendet). Es ist also ein gewissen Aufwand. Aber machbar ist es ohne Probleme. Hier findest Du Informationen darüber, wie man selber Kanalsenken schreibt: http://msdn.microsoft.com/de-de/library/tdzwhfy3(VS.80).aspx 

Mar 7, 2011 at 5:21 PM

Das ist alles sehr intressant ich hab nun ein Zähler analog zu deinem Crypter geschrieben. Der Unterschied von Binary und nicht Binary bei einem DataSet is enorm.

Ich hab ausserdem deine Testfunktion um ein Dataset erweitert um die Antwort etc zu sehen.

Willst du diese Funktion in Zyan als optional einbauen , bis jetz hat man eine Ausgabe die in etwa so aussieht.  Ausgabe von deinem Test erweitert durch eine Dataset funktion.

--

Request: - ClientCounterBefore - Methode - Logon - 248 Bytes
Request: - ServerCounterBefore - ClientID - 2 - IP - 127.0.0.1 - Methode - Unknown - 248 Bytes
Response: - ServerCounterAfter - ClientID - 2 - IP - 127.0.0.1 - Methode - Logon - 23 Bytes
Response: - ClientCounterAfter - Methode - Logon - 23 Bytes
Request: - ClientCounterBefore - Methode - GetRegisteredComponents - 159 Bytes
Request: - ServerCounterBefore - ClientID - 2 - IP - 127.0.0.1 - Methode - Unknown - 159 Bytes
Response: - ServerCounterAfter - ClientID - 2 - IP - 127.0.0.1 - Methode - GetRegisteredComponents - 819 Bytes
Response: - ClientCounterAfter - Methode - GetRegisteredComponents - 819 Bytes
Request: - ClientCounterBefore - Methode - get_SessionAgeLimit - 155 Bytes
Request: - ServerCounterBefore - ClientID - 2 - IP - 127.0.0.1 - Methode - Unknown - 155 Bytes
Response: - ServerCounterAfter - ClientID - 2 - IP - 127.0.0.1 - Methode - get_SessionAgeLimit - 28 Bytes
Response: - ClientCounterAfter - Methode - get_SessionAgeLimit - 28 Bytes
Request: - ClientCounterBefore - Methode - AddEventHandler - 1551 Bytes

....

Response: - ServerCounterAfter - ClientID - 2 - IP - 127.0.0.1 - Methode - Invoke - 16869086 Bytes
{
Args: 18b1d9d2-0461-4eff-89d1-b3ea64ad55e4
Args: IntegrationTest_DistributedEvents.ICallbackComponentSingleton
Args: GetDataSetXML
Args: System.Reflection.ParameterInfo[]
Args: System.Object[]
Response: - ClientCounterAfter - Methode - Invoke - 16869086 Bytes
{
Args: 18b1d9d2-0461-4eff-89d1-b3ea64ad55e4
Args: IntegrationTest_DistributedEvents.ICallbackComponentSingleton
Args:
Args: GetDataSetXML
Args: System.Reflection.ParameterInfo[]
Args: System.Object[]
}

 

Response: - ClientCounterAfter - Methode - Invoke - 1998794 Bytes
{
Args: 988a661e-7118-4a2e-9ac1-58df5acc760f
Args: IntegrationTest_DistributedEvents.ICallbackComponentSingleton
Args:
Args: GetDataSetBinary
Args: System.Reflection.ParameterInfo[]
Args: System.Object[]
}

Singleton Get DataSetBinary passed.
Request: - ClientCounterBefore - Methode - Invoke - 1166 Bytes
{
Args: 895bb80a-1858-46bc-ab84-1ac0bad51bc5
Args: IntegrationTest_DistributedEvents.ICallbackComponentSingleton
Args:
Args: DoSomething
Args: System.Reflection.ParameterInfo[]
Args: System.Object[]
}

Coordinator
Mar 8, 2011 at 8:07 PM

> Willst du diese Funktion in Zyan als optional einbauen

Ja gerne. Bitte lade den Code doch einfach als Patch hoch oder schicken ihn mir per E-Mail als ZIP-Archiv. Das ist am einfachsten.