Laden...

Zyan Communication Framework

Letzter Beitrag vor 9 Jahren 74 Posts 79.349 Views
Zyan Communication Framework

Hallo zusammen,

angeregt durch die Diskussionen über Event Based Components habe ich ein Framework für verteilte Anwendungen geschrieben, welches auch EBCs unterstützt.

Mit Zyan können Komponenten auf verschiedenen Computern laufen und kommunizieren untereinander übers Netzwerk. Darüber hinaus bietet Zyan Zusatzdienste wie Verschlüsselung, Authentifizierung, Sitzungsverwaltung und automatische Übertragung von verteilten Transaktionen (via System.Transactions). Die Kommunikation kann wahlweise über TCP oder HTTP erfolgen. Sicherheitsfeatures etc. sind individuell einstellbar und können - bei Bedarf - auch leicht abgeschaltet werden. Zyan bietet Schnittstellen zur Erweiterung des Systems an (z.B. für benutzerdefinierte Authentifizierung oder eigene Netzwerkprotokolle).

Es werden natürlich auch klassische Komponenten unterstützt, die ++nicht ++nach EBC-Architektur entworfen wurden!

Ihr findet das Projekt zum runterladen, sowie den Quellcode und die Dokumentation (ist noch nicht vollständig, aber wächst fast täglich) unter http://zyan.codeplex.com/.
Es gibt auch eine kleine Beispielprojektmappe, die an einem sehr einfachen Beispiel zeigt, wie verteilte EBCs mit Zyan funktionieren. Hier geht´s direkt zum Download-Bereich: http://zyan.codeplex.com/releases

Das Projekt steht unter der MIT Lizenz und kann somit frei für eigene Zwecke verwendet werden. Jegliche Haftung ist allerdings ausgeschlossen!

Über Kommentare, konstruktive Kritik oder Verbesserungsvorschläge würde ich mich sehr freuen. Vorzugsweise direkt unter http://zyan.codeplex.com/discussions. Wer Bugs findet, kann Sie gerne im Issue Tracker unter http://zyan.codeplex.com/workitem/list/basic eintragen.

angeregt durch die Diskussionen über Event Based Components

Welche Diskussionen meinst du ?
Ich kenne nur Ralph Westphals Statements dazu.

Für nicht EBC Kundige macht das auch mit der Doku natürlich alles keinen Sinn.
Vielleicht kann Zyan hier noch etwas Begeisterungsarbeit leisten. 😃

Hallo Sebastian.Lange,

Welche Diskussionen meinst du ?

die Diskussionen im Forum: Forumssuche nach EBC or EBCs (natürlich nur die Threads vor dem 23.09.2010 00:31).

herbivore

Hallo Sebastian.Lange,

Für nicht EBC Kundige macht das auch mit der Doku natürlich alles keinen Sinn.

Ich bin mit der Zyan-Doku leider noch nicht bei EBCs angekommen. Ich wollte zuerst drin haben, wie man ein verteiltes Hello World mit Zyan zum laufen bringt und wie es grundlegend funktioniert. Ist ja aber auch noch nicht fertig. Ich werde noch ganz ausführlich erklären, wie man verteilte EBC-Style-Anwendungen mit Zyan erstellt.

Die kleine beiliegende Beispiel-Projektmappe ist nur ein mini, mini Demo um das aller grundlegendste zu zeigen.

Vielleicht kann Zyan hier noch etwas Begeisterungsarbeit leisten. 😃

Das hoffe ich. Es ist allerdings auch ein Test für die Praxistauglichkeit. Ich habe vor ein kleines Mini-CRM-System-Beispielprojekt mit EBCs und Zyan aufzusetzen, um auszuloten, ob EBCs für die erstellung von Buisness-Anwendungen wirklich Vorteile bringen. Alles was es im Netz momentan gibt, geht nicht wirklich über Hello World hinaus. Es muss eine Anwendung her, die zumindest halbwegs Real World-Charakter hat. Zuerst musste die Verteilung von EBCs aber erst mal laufen. Das ist mit der aktuellen Zyan-Version nun geschafft.

Zyan geht bei der Verteilung übrigens einen anderen Weg, als der von Ralf Westphal in seinem Beispiel unter Remote Communication mit Event-Based Components und Application Space Vorgeschlagene!

Aber selbst ganz ohne EBCs ist Zyan ein nützliches Kommunikations-Framework für einfache und intuitive .NET zu .NET Kommunikation.

Salute Rainbird

Ich habe mal deinen Quellcode durchgeschaut.

Die Sache sieht sehr interessant aus. Das du die "normalen" Komponenten dann mit einer Wrapperklasse als "MarshalByRefObject" ausgibt, ist natürlich cool 😃.

Von Benutzer, API-Benutzersicht sicherlich mehr als einen Blick wert.

Was mir aber ein wenig missfällt, sind die Kommentare - der Noise - zwischen dem Code, sowie der Gebrauch von Region und folgend, die langen Klassen, die da teilweise vorkommen.

Beispielsweise hast du im ZyanComponentHost in einer Region mit 3, 4 Methoden einen sehr rudimentären "DI-Container" drin, bzw. das Grundstück davon mit Registrierung, Deregistrierung sowie der Ausgabe aller Registrierungen und natürlich das erstellen einer Instanz.
Drin ist auch Singleton. Soweit ich gesehen habe.

Jetzt mal ganz abgesehen von der Komponente an sich, was meinst du zu meinen obigen Kommentaren und wieso nutzt du nicht eine externe Komponente, bzw. nimmst den "ComponentContainer" raus, in eine eigene Klasse?

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Refaktorisierung

Hallo Peter Bucher,

Was mir aber ein wenig missfällt, sind die Kommentare - der Noise - zwischen dem Code, sowie der Gebrauch von Region und folgend, die langen Klassen, die da teilweise vorkommen.

Die Kommentare und Regions sind so gewollt. Ich habe Code-Kommentare in deutschem Klartext sehr schätzen gelernt. Regions finde ich auch sehr praktisch. Aber das ist alles Geschmacksache.
Mit den langen Klassen hast Du allerdings völlig Recht. Die müssen noch Refaktorisiert werden. Vieles ist relativ schnell runtergeschrieben. Ich wollte die Grundfunktionen erstmal am Laufen haben, damit ich den Code veröffentlichen kann. Der Feinschliff kommt dann so nach und nach. Ich bin aber für solche Anregungen sehr dankbar. Das hilft mir, meine Codequalität in diesem Projekt zu steigern.

Beispielsweise hast du im ZyanComponentHost in einer Region mit 3, 4 Methoden einen sehr rudimentären "DI-Container" drin, bzw. das Grundstück davon mit Registrierung, Deregistrierung sowie der Ausgabe aller Registrierungen und natürlich das erstellen einer Instanz.
Drin ist auch Singleton. Soweit ich gesehen habe.

Das wird noch entzerrt und soll auch in separate Klassen aufgeteilt werden. Wie gesagt, ich habe zuerst mal alles in den zentralen Kern reingestopft um auch zu testen, ob das alles so funktioniert. Zuerst wird die Sitzungsverwaltung ausgelagert werden, da diese auch noch Schnittstellen für Erweiterungen spendiert bekommt. Momentan sind nur In-Memory-Sessions möglich, was eine große Einschränkung für die Skalierbarkeit ist. Das wird sich ändern. In diesem Zuge wird auch die Sitzungsverwaltung aus dem Kern ausgelagert.

... wieso nutzt du nicht eine externe Komponente, bzw. nimmst den "ComponentContainer" raus, in eine eigene Klasse?

Es muss einfach sein. Und zwar in Anwendung, Konfiguration und Deployment. Eiserne Regel für das Zyan-Framwork an sich: Eine einzige DLL!
Ich will noch einen Zyan.Server (EXE) schreiben, der als generischer Host-Prozess verwendet werden kann und Dinge wie Deployment und Monitoring adressiert.

Aber wer möchte, kann ohne Änderungen am Code externe DI-Systeme wie Unity zusammen mit Zyan verwenden. Dafür hat der ZyanComponentHost folgende Methode:


/// <summary>
/// Registriert eine bestimmte Komponente.
/// </summary>
/// <typeparam name="I">Schnittstellentyp der Komponente</typeparam>
/// <param name="factoryMethod">Delegat auf Fabrikmethode, die sich um die Erzeugung und Inizialisierung der Komponente kümmert</param>
void RegisterComponent<I>(Func<object> factoryMethod);

Du kannst also einfach eine Factory-Methode übergeben, und so das Erstellen der Komponente in eigenen Code auslagern. Auf welche Art und Weise Du dann die Komponenteninstanz erzeugst, ist Dir überlassen.

Ich will auch bei Zeiten noch ein Beispiel schreiben, wie man sowas mit Unity machen kann.

Hi, ich habe mir auch mal den Code angeschaut:

Was ich am Konzept nicht verstehe: Irgendwie sieht das wie eine Neuentwicklung von WCF aus, zumindest teilsweise.

Warum nicht einfach ein Wrapper über WCF als Schnittstelle zu EBCs und Vereinfachung der Kommunikation?

Warum kein WCF?

Hallo malignate,

Irgendwie sieht das wie eine Neuentwicklung von WCF aus, zumindest teilsweise.

Keineswegs. Es ist vielmehr eine Erweiterung von .NET Remoting.
Ich hatte anfangs gründlich überlegt, ob ich WCF oder .NET Remoting als Basis verwenden soll und habe mich für letztes entschieden.

WCF zwingt einem ein serviceorientiertes Programmiermodell auf. Das ist toll in einem plattformübergreifenden Szenaraio, aber wirft einem für reine .NET zu .NET Kommunikation nur Steine in den Weg. Um meine Entscheidung besser zu verstehen, hier eine Liste der Contra-WCF-Argumente:*Bei WCF gibt es keinen Aufrufkontext (CallContext) der implizit Daten über eine Aufrufkette von mehreren Services transportiert. *Das Erweiterungsmodell von WCF ist wesentlich komplexer als das von .NET Remoting. *WCF unterstützt nicht die schnelle binäre Serialisierung von ADO.NET DataSets (RemotingFormat=Binary; Das hat nicht unbedingt was mit EBCs zu tun, aber ich bin ein großer Anhänger von DataSets und da gefällt es mir natürlich nicht, dass WCF diese nicht optimal unterstützt). *Mit WCF kann man keine Objektreferenzen versenden. *WCF ist zu starr, da man alles (z.B. Callbacks, Faults) explizit über Kontrakte definieren muss. *WCF ist ein Konfigurationsmonster! *WCF unterstützt den BinaryFormatter nicht. *Bei WCF ziehen sich Attribute wie bei einem durchwachsenen Schinken durch den Code. Ich mochte durchwachsenen Schinken noch nie.

Die durchwachsene Schinken-Geschichte führt in der Praxis dazu, dass man den WCF-Service als Fassade für die eigentliche Geschäftkomponente dahinter verwendet. Das bedeutet dann stumpfsinnig Methodenaufrufe über die Service-Fassade meistens 1:1 durchzureichen. Das macht keinen Spaß.

In besonderem Maße ausschlaggebend war die Tatsache, dass es bei WCF keinen Aufrufkontext gibt. Es gibt nur den OperationContext, der aber nur einen Aufruf weit funktioniert. Wenn ich Aufrufketten habe, wie Client -> Service A -> Service B, dann stehe ich mit WCF im Regen.

Warum nicht einfach ein Wrapper über WCF als Schnittstelle zu EBCs und Vereinfachung der Kommunikation?

Das ist eine berechtigte Frage.
Mit WCF einfach ein EBC-Zwischenstück zu bauen, welches die Nachricht vom Ausgangspin aufnimmt und diese zum Eingangspin der entfernten Komponente transportiert, klingt zunächst naheliegend. Ralf hat das so ähnlich in seinem Beispiel mit Application Spaces (Remote Communication mit Event-Based Components und Application Space) aufgebaut. Der Aufbau lässt sich so darstellen:

A<->P...S<->B

A=Komponente A (Geschäftskomponente)
B=Komponente B (Geschäftskomponente)
P=Proxy (Infrastrukturkomponente)
S=Stub (Infrastrukturkomponente)
<-≥Verdrahtung
...=Netzwerkübertragung

Damit Komponente A die entfernte Komponente B konsumieren kann, müssen ihre Pins mit einem Proxy verdrahtet werden. Die Pins von Komponente B müssen auf der Serverseite mit einem Stub verdrahtet werden, damit Nachrichten zwischen den beiden fließen können.
Dauraus ergibt sich eine Verdoppelung der zu ziehenden Drähte! Und das bei jeder entfernten Komponente: Immer und immer wieder.
Okay, stumpfsinnige Verdrahtung ist ein Grundproblem von EBCs, war irgendwann durch einen schicken Designer eingedämmt werden soll. Da will ich nicht schon wieder drauf rumreiten.
Viel schlimmer als der erhöhte Verdrahtungsaufwand ist aber die Tatsache, dass ich die Infrastruktur-Zwischenstgücke das Modell verkomplizieren. Ich muss sie mir immer wegdenken, wenn ich meine Geschäftskomponenten zusammenstecke. Da helfen mir auch keine Boards, da ein Boards nicht in zwei Prozessen leben kann.

Ich will nicht A<->P...S<->B denken müssen, sondern ich will eigentlich A<->B denken. Wenn ich verteilte Geschäftskomponenten zusammenstecke, dann möchte ich auf der Abstraktionsebene dieser Geschäftskomponenten verharren. Infrastrukturkomponenten stören dabei. Deshalb müssen sie transparent gemacht werden. Darum kümmert sich Zyan.

Mit Zyan kann ich A<->B denken. Zwar wird im Clientprozess für B auch ein Proxy verwendet, aber der fühlt sich genauso an wie B und muss leider sein, da B nunmal in einem anderen Prozess lebt. Ich verdrahte A mit dem Proxy von B und diese Verdrahtung wird von Zyan autonatisch auf die echte Komponente B angewendet. Also keine verdoppelten Drähte und keine Infrastruktur-Fremdkörper im Modell.

Ich möchte EBCs gerne in der Praxis einsetzen. Damit das funktionieren kann, müssen EBCs einfach und intuitiv einsetzbar sein. Zumindest in verteilten Szenarien sind EBCs mit .NET-Bordmitteln das definitiv nicht. Mit Zyan wird die Verteilung von EBCs dagegen kinderleicht und geht vor allem von Statten, ohne dass man viel Code hinschreiben muss. Zyan selber ist nicht aus EBCs gebaut, aber das .NET Framework und z.B. WCF ja auch nicht 😉.

Selbst wenn sich bei meinen Praxistests herausstellt, dass EBCs nicht alltagstauglich sind, war die Mühe Zyan zu schreiben nicht vergebens, denn Zyan kann auch mit ganz klassischen Nicht-EBC-Komponenten ungehen. Dann ist es immer noch einfacher und intuitiver als WCF.

Komponentenverwaltung ausgelagert

... wieso nutzt du nicht eine externe Komponente, bzw. nimmst den "ComponentContainer" raus, in eine eigene Klasse?

Ich hab Deinen Vorschlag aufgegriffen und die Komponentenverwaltung nun als separate Klasse rausgezogen. Das ganze nennt sich jetzt Komponenten-Katalog (ComponentCatalog) und kann auch ganz ohne Verteilung genutzt werden.

Der Ansatz hat sich als sehr vorteilhaft erweisen, da ich so ganz leicht einen Komponenten-Katalog in verschiedenen ZyanComponentHosts mit verschiedenen Protokollen hosten kann.

Neu ist in der Version 0.8 auch die Unterstützung von zusammensteckbaren Anwendungen im neuen Namensraum Zyan.Communication.Modularity. Die Klasse ZyanApplication fungiert dabei als Stammobjekt und Microkernel. Sie lädt sog. Module (Gruppierung von Assemblies in einem Unterverzeichnis, welches den Modulnamen darstellt). Module, die sich kennen (also über eine gemeinsame Shared-Assembly verfügen) können über die API miteinander kommunizieren.

edit 19.12.2010: Modularitiy habe ich in Version 1.0 wieder rausgenommen. Das ist ein eigenes großes Thema und hat nichts direkt mir Kommunikation zu tun. Ich werde das Thema in einem anderen Open Source Projekt adressieren.

Das ist alles natürlich noch sehr ausbaufähig.

Kompiliert das auch gegen Mono?

Zyan unter mono

Hallo boonkerz,

ich habe Zyan eben mit dem Mono Migration Analyzer (MoMa) analysieren lassen. Du findest das den MoMa-Prüfbericht unten im Anhang als PDF.

Es sind nur ein paar Kleinigkeiten.

Die CustomErrors-Eigenschaft ist in Mono wohl(noch) nicht implementiert. Die braucht man aber nicht zwingen, damit Zyan läuft. Über CustomErrors wird eingestellt, ob Exceptions vom Server serialisiert und zum Client übertragen werden sollen, oder nicht.

Dann wird an zwei Stellen ein Typvergleich gemacht, der nicht ganz mono konform ist. Sollte auch kein Problem sein, das anzupassen.

Zu guter letzt hat MoMa noch zwei P/Invokes gefunden. Die werden beide vom Zyan.Communication.Security.BasicWindowsAuthProvider abgesetzt. Dieser Authentifizierungsprovider ist optional und speziell für die Prüdung von Windows-Benutzern entwickelt. Da ich diese P/Invokes nicht sinnvoll ersetzen kann, wird der BasicWindowsAuthProvider unter mono nicht funktionieren. Vermutlich würde ihn aber auch kein mono-Entwickler vermissen, da er vom Zweck her schon Windows bezogen ist.

Es sind also keine unlösbaren Probleme. Ich werde den Zyan-Code entsprechend anpassen und einen Test mit mono machen.

Ich versuche es so hinzukriegen, dass MS.NET und mono mit der selben Assembly arbeiten können. Das sollte doch wie folgt funktionen, oder?


public static class MonoCheck
{
    public static bool IsRunningOnMono()
    {
        return Type.GetType ("Mono.Runtime") != null;
    }
}

...

if (MonoCheck.IsRunningOnMono())
    Console.WriteLine("Mono Implementierung");
else
    Console.WriteLine("Microsoft.NET Implementierung");

Neuigkeiten zur mono-Unterstützung von Zyan, werde ich hier posten.

Zyan läuft nun auch mit mono

Hallo boonkerz,

ich habe die kleinen Problemchen im Code behoben und die Änderungen bei Codeplex eingecheckt. Hier kannst Du die erste mono-taugliche Version abrufen: http://zyan.codeplex.com/SourceControl/changeset/changes/4988

Den mono-Test habe ich mit mono 2.8 unter Windows durchgeführt. Ein Test unter Linux steht noch aus (Das aktuelle VMWare Image wird gerade heruntergeladen und ist leider erst in ein paar Stunden fertig 😉)

Aber unter Windows schnurrt Zyan schon auf der mono Laufzeitumgebung, was folgender Screenshot zeigt:

Hallo,

Ich hatte bei meinem Projekt damals auch WCF eingesetzt.
Allerdings war das schon extrem aufwendig.

http://www.thomas-peterson.de/tpwawi/screenshots.html

Nun ist die Frage ob ich das evtl mit deiner Lösung einfacher geht.
Und da ich inzwischen auf Mac OS unterwegs bin 😃

Einfacher

Hallo boonkerz,

Zyan verwendet unter der Haube .NET Remoting. Der Vorteil von .NET Remoting ist, dass man Objektreferenzen übertragen kann und nicht - wei bei WCF - zwangsweise der Serviceorientiertheit verhaftet ist.

mono hat eine sehr gute Unterstützung für .NET Remoting. Deshalb konnte ich Zyan auch in wenigen Minuten unter mono zum laufen bringen. WCF ist nur teilweise in mono implementiert. Aber selbst wenn es zu 100% implementiert wäre, ist WCF generell kompliziert und sehr aufwändig (wenn man nicht nur Standard-0-8-15 machen will).

Wenn meine mono Tests unter Linux (MacOS steht mir leider nicht zur Verfügung) erfolgreich sind (was spätestens nach ein paar kleinen Korrekturen so sein wird), kann man Zyan auch für plattformübergreifende Kommunikation einsetzen.

Was die Einfachheit angeht, sollte Zyan WCF definitiv etwas vorraus haben, da einfache praktische Anwendung mein wichtigstes Entwurfsziel war (bzw. ist, da Zyan ja noch nicht ganz fertig ist).

Es würde mich freuen, wenn Du Dir die Zeit nehmen würdest, um Zyan auf MacOS einfach mal auszuprobieren. Wenn es irgendwelche Fehler gibt, lassen die sich bestimmt ohne großen Aufstand beheben.

Hallo,

Wenn ich mir die Demo so anschaue hätte mir das viel Arbeit gespart.
Im Grunde habe ich ja wcf nur zur übertragung benutzt.
Da war schon extrem viel Overhead dabei.

Ich schau mal ob ich das zum laufen bekomme.
Die Solutions bekomme ich auf allerdings sind die assymblys ja nicht da 😃

Linux Test

Hallo boonkerz,

ich habe eben erfolgreich einen String zwischen zwei mono Prozessen auf Linux mit Zyan versendet. Den aktualisierten Zyan-Code findest Du in folgendem Changeset: http://zyan.codeplex.com/SourceControl/changeset/changes/5062

Quellcode + Binaries des Linux Tests

Hallo boonkerz,

im Anhang findest Du die Test-Solution meines kleinen Linux-Tests inklusive Binaries.
Starte einfach ZyanTest.Server.exe und dann ZyanTest.Client.exe.

Es ist nur eine kleine Echo-Implementierung. Du kannst im Client einen Text eingeben, der dann zum Server versendet wird. Der Server sendet die Antwort wieder 1:1 zum Client zurück.

Wäre super, wenn das auf dem Mac gleich auf Anhieb laufen würde.

Folgendes ist mir beim entwicklen mit monoDevelop aufgefallen, was zu beachten ist:*Zielframework muss von 3.5 auf 4.0 umgestellt werden *Verweis auf System.Core muss manuell zugefügt werden

Wenn Du es zum laufen bringst, kannst Du dann bitte einen Screenshot hier posten?

Läuft soweit 😃

Danke

Zyan 1.0 ist da

Hallo zusammen,

die Testphase ist vorbei. Zyan 1.0 steht zum download bereit: http://zyan.codeplex.com/releases/view/57797.

Wichtigste Neuerung sind die gesenkten Systemanforderungen. Sowohl Client- als auch Serverseitig kommt Zyan jetzt mit .NET 3.5 Client Profile aus.

Methodenaufruf mit NULL Parametern

Hallo rainbird,

ich versuche gerade eine kleine Anwendung auf Zyan umzustellen, da mir Zyan doch sehr gut gefällt.
Nun bin ich auf folgendes Problem gestoßen.
Es gibt bei mir Methoden, die nicht zwingend alle Parameter brauchen, sodass es auch vorkommt, dass ein Parameter mit NULL übergeben wird.
zB.:
Console.WriteLine(proxyA.GetHelloMessage("a",null));

Dies führt aber nun zu einem Fehler bei

            // Alle Parameter durchlaufen
            for (int i = 0; i < args.Length; i++)
            {
                // Typ in Array einfügen
                types[i] = args[i].GetType();
            }

in Zyan ComponentInvoker.cs

Meine Frage wäre, ob dass so von Dir beabsichtigt nicht möglich ist Null zu übergeben, oder ob es Sinn macht da noch etwas zu ändern.

ps.: Allen ein gutes, glückliches, gesundes und auch erfolgreiches neues Jahr 2011

Bug

Hallo luciluke,

Prost Neujahr!

Danke dass Du den Fehler gemeldet hast. Es ist tatsächlich ein Bug im Zyan-Quellcode. Ich werde den Fehler so schnell wie möglich beheben und eine aktualisierte Version freigben. Natürlich muss man auch null übergeben dürfen.

Fehler behoben

Hallo luciluke,

der Fehler ist behoben. Die korrigierte Version 1.0.0.1 kannst Du unter http://zyan.codeplex.com/releases/view/58487 runterladen.

Danke nochmal.

Fehler behoben "Über Nacht"

Guten Morgen rainbird,

ich muß schon sagen, wenn alles so schnell gehen würde ...
Zyan-Ordner getauscht, Programm läuft.
dann kann ich ja direkt weitermachen.
vielen Dank

Hi,

planst du, das IQueryable<T> unterstützt wird? Momentan fliegt sofort eine SerializationException (System.Linq.EnumerableQuery<T> nicht serialisierbar). Sonst läuft das echt gut.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

IQueryable<T>

Hallo Khalid,

habe mit IQueryable<T> noch nie direkt gearbeitet. Das muss man implementieren, wenn man einen eigenen LINQ-Anbieter schreiben will, oder?
Kannst Du kurz beschreiben, was Du genau machen willst und wie Du das versucht hast, mit Zyan abzubilden. Vielleicht lässt sich ja mit ein paar Handgriffen die fehlende Unterstützung in Zyan nachrüsten.

Hi,

ich nutze in vielen Projekten generische Repositories, die eigentlich immer wie folgt aufgebaut sind:


public interface IRepository<T>: IQueryable<T>, IDisposable
{
  void Insert(T entity);
  // Update, Delete und noch Transaktionsgedöns
}

Später hole ich mir dann per IoC die passenden Repositories und kann direkt mit diesen arbeiten.
Kleines Beispiel:
Alle Kunden ermitteln, die von einem bestimmten User angelegt wurden.


using (IRepository<User> users = IoC.Resolve<IRepository<User>>())
using (IRepository<Customer> customers = IoC.Resolve<IRepository<Customer>>())
{
  var result = from u in users
               join c in customers on c.CreatedBy equals u.UserId
               select new { c.Name, u.UserName };
}

Ich habe einfach mal ein neues Interface IUserRepository: IRepository<User> angelegt und dies am Zyan Host registriert. Auf der Clientseite hole ich mir den Proxy. Alle Methoden wie Insert, Update etc. funktionieren auf Anhieb, da war ich schon sehr begeistert. Nur sobald halt das IQueryable Interface genutzt wird, ist halt ende.
Allerdings glaube ich, dass dies gar nicht so einfach umzusetzen ist. Selbst WCF (ausser über ADO.NET Data Services) kann nicht mit IQueryable umgehen. Und einen eigenen Provider habe ich noch nie geschrieben, bzw. nur mal kurz mit rumgespielt. Ganz trivial ist das auch nicht. Die Beispiele auf bei MSDN sind schon ziemlich komplex.

Ich denke also "mit ein paar Handgriffen" wird das nichts 😃. Aber ist auch nicht schlimm. Das ganze was ich oben beschrieben habe, benutze ich auch nur bei Projekten die direkt auf die DB zugreifen. Bei verteilten Anwendungen (N-Tier), habe ich einen anderen Ansatz (keine generischen Repositories und ohne Queryable). Wobei es natürlich schon genial wäre, wenn ich IQueryable über die Leitung jagen könnte, bzw. meine Ansätze vereinen könnte.

Dennoch finde ich das Zyan Framework extrem gut. Ich denke mal bei kleineren Projekten wird es bei mir Einzug erhalten, alleine schon weil es viel weniger Overhead als WCF hat.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

LINQ Integration Zyan

Hallo Khalid,

ich habe ein bischen recherchiert und folgendes Projekt gefunden: MSDN Code Gallery: Expression Tree Serialization
Damit kann man ganz einfach Linq Expression Trees in XML serialisieren und deserialisieren. So könnte man auf dem Client eine Abfrage zusammenbauen, der Zyan Proxy würde erkennen, dass es sich um eine LINQ-Abfrage handelt und den Expression Tree der Abfrage serialisieren. Der serialisierte Expression Tree der Abfrage lässt sich dann auf den Server übertragen und kann dort deserialisiert und ausgeführt werden. Das Ergebnis wandert übers Netzwerk wieder zurück zum Client. Damit das funktioniert, müssen die Entitäten serialisierbar sein. Das sind sie vermutlich aber jetzt schon.

In der Theorie funktioniert es schon (ausprobiert habe ich es noch nicht).

Leider steht der Expression Tree Serialization Code unter der MS-PL Lizenz, die mit der MIT-Lizenz von Zyan nicht verträglich ist. Ich muss mir deshalb erst einen eigenen Expression Tree Serialisierer erarbeiten. Das kann ein Weile dauern. Aber ich finde das Feature so interessant, dass sich der Aufwand lohnt.

Vielleicht geht das auch noch besser, denn von XML-Serialisierung bin ich kein Freund. Es soll ja auch schnell sein.

Wie sieht denn Deine Implementierung von IRepositoty<T> aus?

Hallo,

Wie sieht denn Deine Implementierung von IRepositoty<T> aus?

ziemlich simpel 😃. Da ich mit NHibernate arbeite, werden eigentliche alle Operationen nur das das Repository durchgeschliffen. Methoden wie BeginTransaction liefern also ein ITransaction Interface zurück, welches einfach nur von NHibernate wiederum zurückgegeben wird. Bei verteilten Anwendungen müsste man bei sowas auf Distributed Transactions setzen. NHibernate kann damit von Haus aus leben.
Die Implementierung des IQueryable<T> Interface ist demnach auch sehr einfach. Die Properties ElementType, Expression und Provider werden auch einfach nur durchgeschliffen.

Wenn du magst, kann ich dir aber auch den Quellcode hier posten.

Hinweis von herbivore vor 13 Jahren

Nein, bitte nicht in diesem Thread. Wir sind hier in " Projekte" und da sollen die Thread kurz und übersichtlich und frei von fachlichen Fragestellungen bleiben. Macht das weitere bitte per PM ab und postet hier nur das Endergebnis. Vielen Dank!

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Zyan kann nun auch mit Events umgehen

Ich habe eben die Zyan Version 1.1 veröffentlicht.
Die neue Version hat ein neues Feature, welches einen Post hier im Zyan-Projektthread auf mycsharp.de auf jeden Fall Wert ist:

Zyan unterstützt nun verteilte Events.

Und zwar ganz intuitiv, wie man es von button1_Click in Windows.Forms gewohnt ist. Hier ein kleines Beispiel, wie einfach man in einer verteilten Zyan-Anwendung mit Ereignissen arbeiten kann:

Server


public interface IMiniChat
{
    event Action<string,string> MessageReceived;

    void SendMessage(string nickname, string text);
}

public class MiniChat : IMiniChat
{
    public event Action<string, string> MessageReceived;

    public void SendMessage(string nickname, string text)
    {
        if (MessageReceived != null)
            MessageReceived(nickname, text);
    }
}

Client


private static string _nickName;

...

ZyanConnection connection = new ZyanConnection("tcp://localhost:9010/MiniChat");
IMiniChat chatProxy = connection.CreateProxy<IMiniChat>();

chatProxy.MessageReceived += new Action<string, string>(chatProxy_MessageReceived);

string text = string.Empty;

while (text.ToLower() != "quit")
{
    text = System.Console.ReadLine();
    chatProxy.SendMessage(_nickName, text);
}

...

private static void chatProxy_MessageReceived(string arg1, string arg2)
{
    if (arg1!=_nickName)
        System.Console.WriteLine(string.Format("{0}: {1}", arg1, arg2));
}

Einfacher geht´s wirklich nicht, oder?

Die komplette Beispiel-Projektmappe hängt als ZIP-Datei im Anhang.

Wie siehts mit Request-Response Szenarien aus, zum Beispiel Callbacks für ein spezielles Request.


DoRequest(x => 
   {
      Console.WriteLine(x);
   });

Delegaten als Parameter

Hallo malignate,

momentan wird eine TargetInvocationException geworfen, wenn Du das tust. Das liegt daran dass der Server die Client-Implementierung nicht kennt und den clientseitigen Delegaten deshalb nicht aufrufen kann.

Das Problem ist aber lösbar. Ich muss dem ZyanProxy nur beibringen, Delegaten-Parameter zu erkennen und eine Abfangvorrichtung davorzuhängen und zu verdrahten. Ich denke dass ist nützlich, da es Zyan noch intuitiver machen würde. Deshalb werde ich das in einer zukünftigen Version einbauen. Kann aber etwas dauern, bis ich dazukomme es einzubauen.

Danke für den Hinweis.

Dann habe ich nun folgende Punkte auf meiner Hausaufgabenliste:*Hosting von Anonymen Typen und generell Typen ohne Schnittstelle möglich machen *Verteilte LINQ-Abfragen übers Netzwerk ermöglichen *Delegaten-Parameter erkennen und entsprechend verarbeiten

Zyan 1.2 unterstüzt nun Delegaten-Parameter

Hallo malignate,

Wie siehts mit Request-Response Szenarien aus, zum Beispiel Callbacks für ein spezielles Request.

  
DoRequest(x =>   
   {  
      Console.WriteLine(x);  
   });  
  

Mit der neuen Zyan Version 1.2 funktioniert auch Dein Request-Response Szenario mit Callback.

Sehr schön. Was mir auch noch nicht so gefällt ist das IChannel interface. Das ist ja ganz nett, weil es halt schon existiert, aber total überladen, da grauts einem echt davor , dass zu implementieren.

Für mich wäre MSMQ interessant, aber dsa IChannel zu implementieren macht ja gar kein Spaß...

MSMQ mit Zyan

Hallo malignate,

Was mir auch noch nicht so gefällt ist das IChannel interface. Das ist ja ganz nett, weil es halt schon existiert, aber total überladen, da grauts einem echt davor , dass zu implementieren.

Die IChannel-Schnittstelle hat doch nur die folgenden drei Member:*string Parse(string,string) *string ChannelName {get;} *int ChannelPriority {get;}

Da ist doch nichts überladen. Aber eigentlich müsstest Du zusätzlich zu IChannel noch IChannelReceiver und IChannelSender implementieren, um einen vollständigen eigenen Transportkanal zu schreiben. Aber auch die sind alle nicht überladen. Schau:

IChannelReceiver:*object ChannelData {get;} *string[] GetUrlsForUri(string); *void StartListening(object); *void StopListening(object);

IChannelSender:*IMessageSink CreateMessageSink(string,object,out string)

Von Überladenen Schnittstellen kann also nicht die Rede sein. Man muss sich allerdings intensiv in die Architektur von Remoting einarbeiten. Ich will nicht behaupten, dass es eine triviale Aufgabe ist, einen eigenen Remoting-Transportkanal zu schreiben. Es ist aber nicht schwieriger, als einen eigenen Transport für WCF zu schreiben (eher sogar einfacher). Man bewegt sich immer auf der Ebene von Sockets, und Byte-Streams, wenn man einen eigenen Transportkanal schreibt. Das bringt einfach eine gewisse Komplexität und Systemnähe mit sich.

Da Zyan aber in Sachen Transportkanäle die Infrastruktur von .NET Remoting verwendet, lassen sich Remoting-Kanäle von Drittanbietern ganz eimfach einbinden. Einfach IClientProtocolSetup und IServerProtocolSetup implementieren und die Kanalerzeugung darin kapseln (Methode CreateChannel).

Für mich wäre MSMQ interessant, aber dsa IChannel zu implementieren macht ja gar kein Spaß...

Es gibt bereits fertige MSMQ-Implementierungen für Remoting (und damit auch für Zyan). Diese hier z.B.:
http://www.codeproject.com/KB/IP/msmqchannelnew.aspx
http://www.codeproject.com/KB/IP/msmqchannel.aspx
Dieser MSMQ Remoting Kanal unterstützt das CallContext-Feature von Remoting und sollte deshalb auch grundsätzlich mit Zyan funktionieren. Da MSMQ vom Design her grundsätzlich asynchron arbeitet, werden aber vermutlich nicht alle Zyan-Features korrekt arbeiten, da MSMQ keine Rückgabewerte zurücksendet. Alle Aufrufe verhalten sich vermutlich dann wie OneWay-Aufrufe.

Du musst Dir also nicht die Arbeit machen, und einen eigenen MSMQ-Kanal schreiben. Wenn Du Probleme hast, für den MSMQ-Kanal passende ProtocolSetups für Zyan zu schreiben, helfe ich Dir gerne weiter.

Meine MSMQ-Kenntnisse sind eher theoretischer Natur. Aber ich versuche trotzdem Zyan über MSMQ bei mir zum Laufen zu bringen. Zunächst mal rein experimentell.

Ob Zyan in Verbindung mit MSMQ wirklich sinnvoll ist, wage ich zu bezweifeln. Alleine die Tatsache, dass man bei MSMQ erst auf allen PCs installieren und von Hand (oder über ein Setup-Programm) erst irgendwelche Queues erstellen muss, wiederspricht schon der Grundphilosophie von Zyan. Zyan soll so admin- und konfigurationsfrei wie möglich sein. Das ist bei MSMQ schon nicht gegeben.

Was würde denn passieren, wenn jemand eine Client-Anwendung mit MSMQ z.B. auf einem Terminalserver betreiben würde? Dann müsste doch für jede Instanz der Clientanwendung eine eigene Empfangsqueue angelegt werden, oder?

MSMQ Experimente

Hallo malignate,

ich habe einen Branch mit MSMQ-Integration von Zyan angelegt. Leider konnte ich nicht Testen, ob er funktioniert, da der MSMQ Remoting Kanal von Roman Kiss nur Active Directory aktiviertes Message Queuing unterstützt. Extra Test-VMs mit Domänencontroller aufzustzen ist mir aber momentan zu viel Aufwand für ein Feature, das vermutlich keine große Verbreitung finden wird.

Den Quellcode findest Du hier http://zyan.codeplex.com/SourceControl/changeset/changes/8916. Und zwar im Ordner branches\msmq_integration. Der neuste MSMQ-Kanal von Roman Kiss ist da schon fix und fertig in Zyan integiert. Wenn Du möchtest kannst Du die MSMQ-Integration gerne auf diesem Branch aufbauend testen, debuggen und ggf. weiterentwicklen. Wenn Du es am laufen hast, kannst Du Deine Version als Patch zu diesem Branch bei Codeplex hochladen. Ich merge den Patchcode dann.

Wenn Dir beim aktuellen Stand der MSMQ-Integration etwas unklar ist, kannst Du mich aber trotzdem gerne fragen.

Hallo Khalid,

... planst du, das IQueryable<T> unterstützt wird? Momentan fliegt sofort eine SerializationException (System.Linq.EnumerableQuery<T> nicht serialisierbar). Sonst läuft das echt gut.

Zyan unterstützt jetzt auch verteilte LINQ-Abfragen. Die LINQ-Unterstützung ist im Projekt Zyan.InterLinq implementiert. Du musst diese Assembly zusätzlich zu Zyan.Communication als Verweis zufügen, wenn Du mit verteilten LINQ-Abfragen arbeiten willst.

Weitere Infos zum LINQ Support von Zyan findest Du in folgendem Beitrag im Diskussionsbereich der Zyan Projektseite: http://zyan.codeplex.com/discussions/249427

In der aktuellen Release 1.2 ist die LINQ-Unterstützung noch ++nicht ++enthalten. Du musst Dir also den Quellcode hier runterladen http://zyan.codeplex.com/SourceControl/list/changesets .

So fühlen sich verteilte LINQ-Abfragen mit Zyan an:


// Verbindung zum Zyan-Server herstellen
var conn = new ZyanConnection("tcp://localhost:8085/InterLinqTest")

// Abfrageaktivierter Proxy erzeugen
var proxy = conn.CreateQueryableProxy("CustomerQueryProvider");

// LINQ-Abfrage ausführen, die serverseitig verarbeitet wird
var customers = from customer in proxy.Get<Customer>()
                where customer.CustomerID == 1
                select customer;

Linq2Sql und Entity Framework sollten auch kein Problem sein.

Unter examples\Zyan.Examples.Linq in http://zyan.codeplex.com/SourceControl/changeset/view/9440# findest Du ein Beispielprojekt.

Zyan 2.0 Beta

Hallo Zusammen,

ich habe eine Beta-Version von Zyan 2.0 veröffentlicht. Hier gibts die neue Version zum runterladen: http://zyan.codeplex.com/releases/view/65159

Highlights der 2.0er Version sind:*TCP Duplexkanal für Kommunikation durch clientseitige NAT-Firewalls hindurch *LINQ Unterstützung *Call Interception System *Unterstützung für Delegat-Parametern

Ich würde mich über Feedback freuen.

Viel Spaß beim Ausprobieren der Beta.

Zyan ist bereit für die Cloud

Hallo zusammen,

Zyan-Anwendungen lassen sich nun auch mühelos in Windows Azure hosten. Weitere Details dazu: http://zyan.codeplex.com/discussions/259397

Wer das Endergebnis mal ausprobieren möchte, kann sich den kleinen MiniChat-Client im Anhang runterladen. Es handelt sich um ein Instant Messaging Beispiel, welches mit einer zentralen Zyan-Serverkomponente arbeitet, die in Azure gehostet wurde.

Einfach im Login-Fenster einen beliebigen Nickname eingeben und als Server-URL 'tcpex://ZyanMiniChat.cloudapp.net:9010/MiniChat' auswählen. Über die Instanzen des MiniChat-Clients kann man sich weltweit miteinander unterhalten.

Den kompletten Quellcode inklusive Azure Hosting gibts im Zyan Quellcode Repository (http://zyan.codeplex.com/SourceControl/list/changesets) im Order examples\Zyan.Examples.AzureHosting.

Viel Spaß beim ausprobieren.

Zyan 2.0 Stable

Die finale Version von Zyan 2.0 ist fertig.

Hier gibts die Bianries zum runterladen: http://zyan.codeplex.com/releases/view/62104

Zyan 2.1

Mit etwas Verspätung auch hier die Ankündigung der neusten Zyan-Version 2.1.

Neu in Zyan 2.1
*Unterstützung für Generische Methoden *Unterstützung für deterministische Ressourcenfreigabe

    • Dispose wird nun automatisch bei Komponenten aufgerufen, dei IDisposable implementieren
    • Alternativ Unterstützung für externe Aufräummethoden *Unterstützung für LINQ-Abfragen an beliebige veröffentlichte Komponenten *System.Linq.Expression wird als Parameter und Rückgabetyp unterstüzt *Keine speparaten DLLs für LINQ-Unterstützung mehr nötig *Serverseitige Unterstützung für MEF (Nur unter .NET 4.0!) *Duck typing *NUnit Test Projekt (MSTest und NUnit Frameworks werden nun unterstützt) *Zahlreiche Verbesserungen der Mono Interoperabilität in TcpExChannel und InterLinq *Dedizierte Projektmappe für MonoDevelop 2.x IDE *Gefixte Bugs: #1046, #1083, #1094

Binaries gibt`s hier: http://zyan.codeplex.com/releases/view/68252

NuGet-Paket gibt´s hier: http://nuget.org/List/Packages/Zyan

Starker Namen

Ist es für die nächsten Versionen geplant, dass es einen "starken Namen" gibt?

Starker Name

Hallo ..Heinz..,

Danke für den Hinweis. Ich habe einen Starken Namen für Zyan 2.2 eben auf die TODO-Liste gesetzt. Hier kannst Du den Status der Entwickleraufgabe verfolgen: http://zyan.codeplex.com/workitem/1231

Bis zum release von Zyan 2.2 kannst Du Dir behlfen indem Du die Quellen von Zyan herunterlädst und zum Projekt Zyan.Communication selber einen SNK-Schlüssel zufügst und das Projekt anschließend neu kompilierst.

Für .NET 4.0, .NET 3.5 und mono gibt es getrennte SLN Dateien im Ordner \source.

Hallo Rainbird,

danke für die schnelle Antwort und fürs

genau so habe ich es gemacht und den Key selbst hinzugfügt. Aber wenn es schon ein Nuget Package gibt, dann ist das schon bequemer 😁

Super Komponente. Hat mir viel Arbeit erspart 🙂

Gruß ..Heinz..

Hi 😃,

ich habe mehrere Verbindungen zum Zyan-Server aufgebaut (uns sie nach Verwendung wieder Dispose).

Nun bekomme ich jedoch den Fehler:> Fehlermeldung:

Ein Socketvorgang konnte nicht ausgeführt werden, da dem System Pufferspeicher fehlte oder eine Warteschlange voll war

Woher kann das kommen? Ich habe schon gelesen, dass es vorkommt, wenn man einen Port ≥ 5000 verwendet oder wenn zu viele gleichzeitige Verbindungen offen sind.

Fehler

Hallo ..Heinz..,

damit ich den Fehler reproduzieren kann, brauche ich noch ein paar Informationen:*Welche Zyan -Version hast Du eingesetzt? *Auf welchen Betriebssystemen laufen Client und Server? *Welches ProtocolSetup hast Du verwendet? *Welche Sicherheitsfeatures hast Du aktiviert? *Wie viele Verbindungen hast Du aufgebaut?

Am besten wäre ein Codeschnipsel, wie Du vorgegangen bist.

Hinweis von herbivore vor 13 Jahren

Und das ganze bitte per PM. Das abschließende Ergebnis kann und sollte natürlich wieder in den Thread.

Fehler behoben

Hallo ..Heinz..,

ich habe den Fehler - hoffentlich - behoben. Problemursache war, dass der Client-Remotingkanal bei Aufruf von Dispose nicht richtig deregistriert wurde.

Du kannst den aktualisierten Zyan-Quellcode hier runterladen: http://zyan.codeplex.com/SourceControl/changeset/changes/13345

Hallo Rainbird,

das wars gewesen 😃 Super Arbeit. Vielen Dank

Gruß

..Heinz..

Zyan 2.2 ist released

Hallo zusammen,

für das Kommunikationsframework Zyan wurde soeben die neue Version 2.2 veröffentlicht. Neben jeder Menge Bugfixes bringt die neue Version folgende Neuerungen mit:*Weite Teile des Zyan-Kerns wurden refaktorisiert *Clientseitige MEF (Managed Extensibility Framework) Integration *Einfachere Integration von eigenen Remoting-Senken möglich *Vordefinierte Protocol Setups sind nun individuell erweiterbar *Abonnieren von entfernten Delegaten und Ereignissen ist nun wesentlich schneller *Zyan kann nun unerwartete Verbindungsabbrüche erkennen *Die neue Basisklasse SessionManagerBase vereinfacht die Implementierung einer eigenen Sitzungsverwaltung *Zyan.Communication.dll hat nun einen Starken Namen (ist mit SNK-Datei signiert) *Strikte Versionierung bei Serialisierung kann nun abgeschaltet werden

Auf folgender Webseite (in Englischer Sprache) gibts eine detaillierte Übersicht über die Änderungen: What's new in Zyan 2.2?

Die neuen Binaries gibts entweder direkt bei Codeplex oder als NuGet-Paket.

Zyan 2.2 unterstüzt .NET Framework 3.5, .NET Framwork 4.0 und Mono 2.8 (oder höher).

Offene Fragen beantworte ich gerne hier auf mycsharp.de oder im Zyan-Diskussionsbereich.

Zyan 2.3

Die neue Zyan Version 2.3 ist fertig.

Folgende Neuerungen stecken drin:*Sitzungsgebundene Ereignisse (session-bound events) *Serverseitige Ereignisfilter *Ereignis-Abos werden beim wiederverbinden automatisch wiederhergestellt *Call Interception wurde verbessert (Pausierbar + Erweiterungen für leichteres Erstellen von Abfangregeln) *HttpCustomClientProtocolSetup unterstützt nun Proxy Server (auch mit Authentifizierung) *Remote Streaming funktioniert und wurde durch Unit Tests getestet *Zahlreiche Bugs wurden behoben

Weitere Informationen, die aktuellen Binaries und den vollständigen Quellcode gibts auf der Zyan Codeplex-Seite.

Das Zyan Communication Framework ist nun auch auf Ohloh zu finden: http://www.ohloh.net/p/zyan

Setzt ihr Zyan in Real-World-Projekten ein?
Falls ja, würde ich mich über eine kurze Rückmeldung im Zyan-Diskussionsbereich Projects using Zyan Framework (Thread ist allerdings in Englisch!) sehr freuen.

Hallo Rainbird,

ich verwende die aktuelle Version (2.3) und habe vllt. einen "Fehler" festgestellt.

Ich habe einen Server, der eine Funktion implementiert, die als Parameter eine List<T1> erwartet und eine List<T2> zurück gibt.

public List<T2> Function<T1, T2>(List<T1> list)

Wenn ich vom Client jedoch diese Funktion aufrufe, bekomme ich die Fehlermeldung> Fehlermeldung:

Methode nicht gefunden

Ich habe einen Test gemacht, ob es vllt. daran liegt, dass ich zwei verscheiden Typen verwende (T1 und T2) und habe nur T1 verwendet. Da kan allerdings der gleiche Fehler.

Wenn ich in der Funktion jedoch den Typ fest angebe, dann funktioniert es.

public List<T1> Function<T1>(List<Article> list)

Woran kann es liegen, dass ich keinen anonymen Typparameter als Funktionsparameter benutzen kann?

Gruß

..Heinz..