Laden...

Fragen, Diskussion, Kritik zu Projekt ".NET Applikationsserver"

Erstellt von wdb.lizardking vor 16 Jahren Letzter Beitrag vor 9 Jahren 142.270 Views
3.728 Beiträge seit 2005
vor 16 Jahren
Rollenbasierte Sicherheit

Hallo boonkerz,

Rollenbasierte Sicherheit ist bereits in meinem Applikationsserver integriert. Ich ordne jeder logischen Rolle eine Windows-Sicherheitsgruppe zu. Praktisch dabei ist, dass man die Standard-Windows-Tools (Lokale Benutzer und Gruppen, Active Directory Benutzer und Computer) verwenden kann, um Rollen der Anwendung zu verwalten. Durch die Verwendung des Windows-Sicherheitssystems wird Single-Sign-On an Active Directory automatisch unterstützt.

Es spricht nichts dagegen, die Rollen auch zur (de)Aktivierung von Oberflächenelementen zu verwenden. Bei intensiver Nutzung sollte man die Rollen des Benutzers allerdings clientseitig cachen.

B
122 Beiträge seit 2004
vor 16 Jahren

Hallo,

Nun ja ich muß ja die rollen bzw. gruppen im appserver bestimmte Rechte geben. z.b. du darfst kunden anlegen.

Hast du dazu eine idee? einfach uuid der gruppe mit dem recht in der db speichern?
Ich habe mich damit noch nicht so intensiv beschäftigt da es dazu auch irgendwie wenig infos gibt.
Bei mir wird der User in der Anwendung z.b. immer gehalten quasi mit nem singleton. da wäre es ja nun so das mann bei z.b. buttons die disabled eigenschaft per user.hasRole(this.button.id)
die id wäre dann z.b. CustomerAdd oder sowas.

damit könnte mann sein eigenes button control nutzen und hätte immer gleich die rechte verwaltung.
Nur ist das die beste Lösung 😁

MFG

3.728 Beiträge seit 2005
vor 16 Jahren
Rollenprüfungen

Hallo boonkerz,

Die Rechte machst Du an den logischen Rollen fest (z.B. dürfen alle Benutzer Artikeldaten lesen und anzeigen, die direkt oder indirekt Mitglied der Rolle "Product Reader" sind). Diese logischen Rollen kannst Du als Entwickler frei festlegen und auch im Quellcode hart-codiert verwenden.
In meiner Lösung wird jeder logischen Rolle eine physikalische Windows-Sicherheitsgruppe zugeordnet (In der Datei roles.xml). Alle Windows-Benutzer, die Mitglied dieser zugeordneten Sicherheitsgruppe sind, erhalten damit automatisch die Privillegien der verknüpften logischen Rolle.
Es gibt verschiedene Ansätze, wie man seine Rollen strukturieren kann. Man könnte z.B. auch Akteure aus Anwendungsfällen als Rollen abbilden. Wenn ein Button z.B. nur von Mitarbeitern der Buchhaltungsabteilung gedrückt werden können soll, muss das Formular nur auf die entsprechende Rolle prüfen und das Prüfergebnis der Enabled-Eigenschaft des Buttons zuweisen.

Wenn Rollen aus irgendeinem Grund zu grobkörnig sind, muss man statt dessen ACLs (Access Control Lists) verwenden (Wie das NTFS-Dateisystem). Aber auch dafpr gibt es fertige Klassen im .NET Framework 2.0.

B
122 Beiträge seit 2004
vor 16 Jahren

Hallo,

Jup nur genau für sowas gibts keine Beispiele z.b. wie ich Forms möglichst flexibel mache damit ich nicht in jedem Form jeden Button anfassen muß.

Na mal sehen werde ich mir mal was ausdenken 😁

MFG

D
2 Beiträge seit 2008
vor 16 Jahren
AppServer

Hi Rainbird,

ich habe mir den AppServer angesehen.
Es gibt einige Fragen, die ich habe, vielleicht kannst (oder magst) Du sie mir beantworten

  1. Warum wird die Kommunikation der Daten über DataSets gehandhabt? Wäre eine generische Schnittstelle, die den tatsächlichen Träger der Daten "versteckt" nicht eine bessere Variante?->SOAP o. Generics Interfaces?
  2. Du hast einige Komponente "BusinessLogic" genannt, wenn ich es richtig interpretiere, garantieren diese Komponenten die Datenkonsistenz der zu schreibenden Daten. Ich hatte mit letzterem ein Objektmodell assoziiert. Den BusinessLayer schreibe ich eher höhere Funktionen zu, z.B. Abarbeitung von Rechenprozessen, etc.
  3. In Deinem Code gibt es mehrere Stellen, die generiert wurden. Mit welchem Tool machst Du das?

Da5id

P.S.: Für mich ein sehr hilfreiches Sample, da ich gerade eine FatClient-basierte Software in eine multi-tier software umbauen muß.

3.728 Beiträge seit 2005
vor 16 Jahren

Hallo da5id_,

gerne will ich Deine Fragen beantworten.

  1. Warum wird die Kommunikation der Daten über DataSets gehandhabt? Wäre eine generische Schnittstelle, die den tatsächlichen Träger der Daten "versteckt" nicht eine bessere Variante?->SOAP o. Generics Interfaces?

Ich verstehe die Frage nicht richtig. DataSets sind Datentransferobjekte (DTOs) und SOAP ist ein XML-basiertes Kommunikationsprotokoll um entfernte Methodenaufrufe und Datenübertragung. Die Frage ist also nicht SOAP oder DataSets, sondern SOAP (meistens HTTP + XML) oder Binärer Datenstrom. Für Anwendungen die im LAN laufen, hat SOAP zu viel Protokoll-Overhead und ist damit unnötig langsam. Hinzu kommt, dass keine vernünftige Authentifizierung über SOAP möglich ist. Dazu müsste man wieder WS-* Protokolle implementieren und wäre damit bei WCF. WS-* würde bei einer abgeschlossenen n-Tier-Anwendung aber keinen Sinn machen. SOAP ist okay bei Datenübertragung übers Internet und für Anwendungen, die plattformübergreifend Kommunizieren müssen. Auch wenn momantan viel über Webservices, SOAP, SOA und EAI geredet wird, sind diese Kriterien für viele Anwendungen gar nicht relevant. Wenn ich Interoperabilität bei meiner Lösung haben will/muss, würde ich einen C#-Webservice schreiben, der die DataSets entsprechend aufbereitet und die Kommunikation nach außen kapselt.

Ich verwende schnelle binäre aber properitäre Kommunikation. Alle Aufrufe werden verschlüsselt und es wird Windows-Authentifizierung eingesetzt. Deshalb unterstützt die Lösung in einer Active Directory-Umgebung standardmäßig Single-Sign-On.

  1. Du hast einige Komponente "BusinessLogic" genannt, wenn ich es richtig interpretiere, garantieren diese Komponenten die Datenkonsistenz der zu schreibenden Daten. Ich hatte mit letzterem ein Objektmodell assoziiert. Den BusinessLayer schreibe ich eher höhere Funktionen zu, z.B. Abarbeitung von Rechenprozessen, etc.

Ich werde bald eine neue Version des Beispielprojekt veröffentlichen, welche zusätzlich zur Artikelverwaltung noch eine Lagerverwaltung enthält. Dort wird dann die gesamte Buchungslogik in den Geschäftskomponenten liegen. Beim Artikelstamm gibt es leider keine Rechenprozesse. Da werden lediglich Stammdaten angelegt, die von anderen Modulen (z.B. der Lagerverwaltung) verwendet werden können. Wenn es in der Artikelverwaltung Rechenprozesse etc. geben würde, wären diese natülich auch in der BusinessLogic implementiert.

  1. In Deinem Code gibt es mehrere Stellen, die generiert wurden. Mit welchem Tool machst Du das?

Was meisnt Du? Ich habe ein Visual Studio 2005 Standard Edition und einen SQL Server 2005 Express Edition für die Entwicklung eingesetzt. Sonst nichts.

D
2 Beiträge seit 2008
vor 16 Jahren

Hi,

Bei 1. mir ging es um eine Abstraktion der Kommunikation möglichst ohne .Net Objekte, da meine Firma plant, weitläufig multiplattform Unterstützung zu gewährleisten, -> Java. Ein Großteil der UI auf dem Client wird weiterhin auf .net basieren. Dementsprechend wäre SOAP eine Alternative. DataTables werden nicht mehr möglich sein. Gibt es noch eine andere Alternative?

Vergiß 3. hab mich verguckt.

Freu mich schon auf den erweiterten Business Layer 🙂

da5id

1.378 Beiträge seit 2006
vor 16 Jahren

Hallo Rainbird,

ich habe mir jetzt etwas Zeit genommen mich durch die Klassen und Methoden durchzuarbeiten um deren Bedeutung zu verstehen und muss zugeben das ich sehr begeistert bin 🙂

In der kürze, habe ich bestimmt nicht alle rafinessen entdeckt, die du hier eingebaut hast.
Stellen die mir extrem gut gefallen haben sind die ServiceFactory(einfach das Prinzip wie die Services generisch zur Verfügung gestellt werden) und darüber hinaus die DataAcces Klasse.(Vermutlich ist das alles nicht soooo besonders, aber wenn ich das mit meiner bisherigen Programmierweise vergleiche ein Traum 🙂)

Der Umgang mit dem CallContext gefällt mir auch sehr gut und habe ich mir bereits in meiner aktuellen Applikation abgeschaut.

Ein wenig verwirrend finde ich das SecurityService und dort speziell die Logon und IsTrustWorthy Methoden(oder statt verwirrend einfach nur unübersichtlich?).

Hätte sich für die Log funktionen nicht AOP angeboten? (Habe damit aber keinerlei Erfahrung)

Alles in allem find ich das Projekt sehr gelungen. Ich müsst jedoch ähnliches selbst nachprogrammieren, um es wirklich ins blut einfließen zu lassen.

Lg XXX

3.728 Beiträge seit 2005
vor 16 Jahren

... mir ging es um eine Abstraktion der Kommunikation möglichst ohne .Net Objekte, da meine Firma plant, weitläufig multiplattform Unterstützung zu gewährleisten, -> Java.... ...Gibt es noch eine andere Alternative?

Wenn Du wirklich plattformneutral sein willst, dann verwende überhaupt keine Objekte, sondern arbeite mit XML-Dokumenten. Mittels DOM, XPath, XQuery und XSLT kannst Du damit sehr komfortabel arbeiten und bist um Welten flexibler als mit Objekten. XLST verwandelt ein XML-Dokument außerdem im handumdrehen in ein schönes HTML oder PDF-Dokument. Oder auch in die Datenstruktur einer anderen Anwendung.
SOAP wird zwar immer an erster Stelle genannt, wenn es um Interoperabilität geht, aber in der Praxis gibt es viele Probleme. SOAP ist nicht gleich SOAP. Man kann z.B. dokumentorientiert arbeiten oder klassisch entfernte Methoden aufrufen.

Es gibt aber sehr gute Alternativen zu SOAP. Da wären z.B. die sogenannten REST-Webservices. Das ist direkte XML-Kommunikation über HTTP. Da XML-Dokumente sowieso selbstbeschreibend sind, braucht REST weder aufwändige Header, noch Metadaten. Client und Server kommunizieren über XML-Dokumente. Mittels XML-Schemas kann jede Seite prüfen, ob eine Anfrage oder ein Ergebnis auch valide ist. REST ist auch sehr Firewall freundlich und absolut plattformneutral. Alles was Bytes über HTTP senden und empfangen kann, ist in der Lage mit REST-Webdiensten zu kommunizieren. Details zu REST und ein Vergleich mit SOAP findest Du hier: http://www.oio.de/public/xml/rest-webservices.htm

Ich mag es gerne einfach, leichtgewichtig aber trotzdem leistungsfähig. Deshalb würde ich in REST den Vorzug geben. SOAP ist in meinem Augen ein komplizierter Krempel.

Ein wenig verwirrend finde ich das SecurityService und dort speziell die Logon und IsTrustWorthy Methoden(oder statt verwirrend einfach nur unübersichtlich?).

Diese Funktionen sind deshalb etwas aufwändiger, da sie außer der Authentifizierung die komplette Sitzungsverwaltung implementieren. Ich habe auf Performanz Wert gelegt. Deshalb werden Sitzungen nach erfolgreicher Anmeldung gecached. Die Sitzungen sind nur für eine bestimmte Zeit lang gültig (Über App.config einstellbar). Während dieser Zeit vertraut der Applikationsserver dem aufrufenden Client, wenn er den korrekten Sitzungsschlüssel im Aufrufkontext mitführt. Ist die Sitzung aber abgelaufen, muss die Identität des Aufrufers erneut überprüft werden. Durch diesen Sitzungs-Cache muss die Identitätsprüfung nicht bei jedem Aufruf, sondern nur alle paar Minuten, durchgeführt werden. Aufrufe mit gültiger Sitzung werden praktisch "durchgewunken" und müssen nicht jedesmal den vollen Sicherheitscheck machen. Trotzdem ist das System sehr sicher (wenn man die Sitzungslebensdauer nicht zu lang einstellt), da ein Angreifer nur wenige Minuten Zeit hat, um eine Sitzung zu kapern und sich damit Rechte zu erschleichen. Das dürfte von Außen aber sehr schwer sein, da der Remoting TCP-Kanal alles verschlüsselt überträgt. Wenn beide Computer Teil einer Active Directory-Domäne sind, wird automatisch Kerberos verwendet, was nicht nur die Identität des Benutzers, sondern auch noch die des jeweils anderen Computers prüft.
Wenn die volle Identitätsprüfung bei jedem Aufruf einer Dienstmethode erfolgen müsste, würde das bei vielen Aufrufen die Leistung sehr negativ beeinträchtigen. Deshalb der Sitzungs-Cache.
Für das was der Sicherheitsdienst alles tut, finde ich nicht, dass es viel Code ist.

In der Anwendung ist die Sache auch einfach. Ein Dienst kann seinen Host (also den Applikationsserver) jederzeit Fragen, ob der aufrufende Client denn auch wirkich vertrauenswürdig ist. Wenn der aufrufende Client eine gültige Sitzung hat, oder seine abgelaufene Sitzung im Zuge der Vertrauenswürdingskeitsprüfung erneuert werden konnte, ist er vertrauenswürdig. Hat er keine Sitzung (wenn ein Client z.B. versucht einen Dienst zu konsumieren, ohne sich vorher per Logon am Applikationsserver des Dienstes anzumelden) oder seine abglaufene Sitzung wurde nicht erfolgreich erneuert wurde (weil er z.B. plötzlich nicht mehr korrekt vom Betriebssystem authentifiziert werden konnte und er in Wirklichkeit ein ganz schlimmer Finger ist), ist der Client nicht vertrauenswürdig. IsTrustworthy ist der Grundpfeiler der Sicherheit des Systems.

Wenn man nicht nur prüfen will, ob ein Aufrufer grundsätzlich vertrauenswürdig ist, sonder auch gleich wissen will, ob er einen VIP-Ausweis für die Backstage-Zone hat, verwendet mann statt IsTrustworthy die Methode IsInRole("Rolle"). IsInRole prüft automatisch ob er vertrauenswürdig ist. Wenn ja, wird erst der Rollenprüfung durchgeführt. Da ausschließlich das Windows-Sicherheitssystem zum Einsatz kommt, werden die Logischen Rollen auf Windows-Sicherheitsgruppen gemappt. Die Rollenprüfung wird so einfach auf das Betriebssystem abgewälzt. Das ist auch gut so, denn eine Gruppe kann ja wieder Mitglied einer anderen Gruppe sein. Windows führt diese Rollenprüfungen sehr schnell und zuverlässig durch. Die Applikationsserver-API muss die logischen Rollennamen, welche hart-codiert im Code verwendet werden (z.B. "Product Reader") in die passenden Windows-Gruppen auflösen. Der Applikationsserver verwendet - so vorhanden - automatisch Active Directory für die Rollenbasierte Sicherheit. Single-Sign-On frei Haus!
Selbst wenn der Client eine ASP.NET Webseite ist, klappt das im Intranet super, da die ASP.NET-Seite impersonieren kann.

Ist die Funktion von Logon und IsThrustworthy nun etwas verständlicher?

Was das Logging angeht, wollte ich auch bei den .NET 2.0 Bordmitteln bleiben. Natürlich könnte man Logging und Transaktionalität als Aspekte implementieren. Aber eben nicht mit den Bordmitteln. Da müsste man schon PostSharp o.ä. einsetzen.

T
108 Beiträge seit 2005
vor 16 Jahren

Hi Rainbird!

An dieser Stelle noch mal ein große Dankeschön!!

Ich habe anhand deines Beispiels mal angefangen eine Anwendung zu erstellen. Es hilft mir sehr, immer wieder bei Dir "nachzusehen", wie Du das ein oder andere gelöst hast.

Freue mich schon, auf die von Dir gennanten Erweiterugen 🙂

Was einmal war, wird nie wieder sein...

S
243 Beiträge seit 2005
vor 16 Jahren

Bin auch schon sehr gespannt, vor allem auf die umsetzung mit web-services anstatt remoting 🙂

Mir stellt sich noch die frage, wie man eigentlich die systemanforderungen für einen applikations-server spezifiziert? Ich mein wie legt man fest, was die maschine auf der er läuft für eine konfiguration haben soll/muss? Prozessorleistung, RAM, etc. Hat da jemand erfahrung unter den entwicklern?

344 Beiträge seit 2007
vor 16 Jahren

Hallo, das Problem mit Windows (IIS) spüre ich selber.
Im Gegensatz zu z.b. Linux ist Windows unglaublich unflexibel.
Akuteller Fall: PHP Settings können nur globale konfiguriert werden.
Unter Linux kann man das alles schön einzeln machen.

Vorteile von Windows (Server 2003) finde ich ist
stabilität und das Ressourcenmanagement.
Die finde ich besser als bei den meisten anderen Betriebssystemen.

Verbunden mit dem hohen Preis und den vielen kleinen (aber nervigen)
einschränkungen von Windows werde ich demnächst auf ein Linux OS wechseln
müssen, da das neue PHP5 unter Windows (mit seinen globalen einstellungen)
der Horror ist. Administrative Software für Windows z.B. Plesk helfen zwar
den Server sicher zu konfigurieren, aber auch hier gibt es einschränkungen
die ich bei anderen Betriebssystemen nicht habe.

👶-> :]-> 8o-> 🙂

T
108 Beiträge seit 2005
vor 16 Jahren

@RPlaner: Es tut mir leid, aber mir bleibt der Sinn verschlossen, was Dein Problem mit dem Applicatin Server von Rainbird zu tun haben.

Was einmal war, wird nie wieder sein...

344 Beiträge seit 2007
vor 16 Jahren

Habs grad gemerkt, Sry, bin ins falsche Topic gerutscht 8o ?(
Da wollte ich gar net hin ^^

Sry

👶-> :]-> 8o-> 🙂

3.728 Beiträge seit 2005
vor 16 Jahren
Neue Version des Beispiels

Hallo,

es gibt unter .NET Applikationsserver eine neue Version des n-Tier Architekturbeispiels.

D
5 Beiträge seit 2008
vor 16 Jahren

Hallo Rainbird,

Super und funktioniert wie gewohnt einwandfrei! 😁
Was mir aufgefallen ist:
Ein Aufruf des Dialoges "Bestandsänderung" lockt den aktuellen DS nicht, womit unterschiedliche User quasi gleichzeitig den Bestand ändern können.

Nochmals danke für dieses Super Beispiel.

Wer früher stirbt ist länger tot =)

M
233 Beiträge seit 2006
vor 16 Jahren

Hallo,

ein Dankeschön erst einmal an Rainbird, der das Beispiel online gestellt hat 😉
Was mir aufgefallen ist, daß die Connectionstrings in jeder Library in die App.Config gesetzt wird.
Das ganze lässt sich wohl besser handlen, wenn ich eine einzige App.Config in der Main des Programmes habe ?
Oder irre ich mich hier ?

3.728 Beiträge seit 2005
vor 16 Jahren
Bugs

Danke für die Hinweise!

@DaFenix: Das ist mir durch die Lappen gegangen. Füge einfach folgenden Code in den ChangeStockDialog ein:


/// <summary>
/// Wird aufgerufen, wenn der Dialog geladen wird.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ChangeStockDialog_Load(object sender, EventArgs e)
{
    // Versuchen, eine Sperre auf das Produkt zu bekommen 
    LockingInfo lockInfo = ApplicationServer.AcquireLock("Stocks", _result.StockID.ToString());

    // Wenn die Sperre nicht zugeteilt wurde ...
    if (!lockInfo.Success)
    {
        // Warnmeldung anzeigen
        MessageBox.Show(lockInfo.Message, "Rainbird´s n-Tier Example", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

        // Dialog schließen
        Close();
    }
}

@m@crotron: Es gibt nur eine App.config, die einen Connectionstring enthält und die liegt direkt beim ApplicationServer-Prozess. Die App.config des Windows-Clients enthält keine Connectionstrings. Oder meinst Du was anderes?

M
233 Beiträge seit 2006
vor 16 Jahren

@m@crotron: Es gibt nur eine App.config, die einen Connectionstring enthält und die liegt direkt beim ApplicationServer-Prozess. Die App.config des Windows-Clients enthält keine Connectionstrings. Oder meinst Du was anderes?

in der Library, wo das InventoryDataSet.xsd gelegen ist, da ist noch eine App.Config.

D
5 Beiträge seit 2008
vor 16 Jahren

Danke für die Hinweise!

@DaFenix: Das ist mir durch die Lappen gegangen. Füge einfach folgenden Code in den ChangeStockDialog ein:

  
/// <summary>  
/// Wird aufgerufen, wenn der Dialog geladen wird.  
/// </summary>  
/// <param name="sender"></param>  
/// <param name="e"></param>  
private void ChangeStockDialog_Load(object sender, EventArgs e)  
{  
// Versuchen, eine Sperre auf das Produkt zu bekommen  
LockingInfo lockInfo = ApplicationServer.AcquireLock("Stocks", _result.StockID.ToString());  
  
// Wenn die Sperre nicht zugeteilt wurde ...  
if (!lockInfo.Success)  
{  
// Warnmeldung anzeigen  
MessageBox.Show(lockInfo.Message, "Rainbird´s n-Tier Example", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);  
  
// Dialog schließen  
Close();  
}  
}  
  

Hallo Rainbird,

dein Code löst das Problem leider nicht ganz, da wenn der Dialog geschlossen wird das Lock stehen bleibt. Habe mir erlaubt das ganze ein wenig abzuändern. Wen es interessiert, hier ist der Code:

Das LockInfo Objekt in der Klasse bekannt machen.


// Referenz auf den ggf. gesperrten Datensatz
private LockingInfo lockInfo = null;

Im Closing Ereignis des ChangeStocks Dialogs folgendes einfügen:


/// <summary>
/// Entfernt Datensatzlock, sofern vorhanden
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ChangeStockDialog_FormClosing(object sender, FormClosingEventArgs e)
{
if (lockInfo != null)
{
// Falls Lock vorhanden..
if (lockInfo.Success)
{
// Lock entfernen
ApplicationServer.ReleaseLock(lockInfo.LockID);
}
}
}

Wer früher stirbt ist länger tot =)

3.728 Beiträge seit 2005
vor 16 Jahren
Bugs, Bugs, Bugs

@m@acrotron: Die App.config im Projekt Rainbird.Examples.NTier.Inventory.Contracts kannst Du bedenkenlos löschen. Visual Studio hat die automatisch angelegt, als ich aus dem Server Explorer Tabellen ins DataSet gezogen habe. Diese App.config wird aber nicht verwendet. Ich habe das nur übersehen und mich bereits auf meinem Blog darüber geärgert, dass Visual Studio das so macht: http://yellow-rainbird.de/blogs/rainbird/archive/2008/03/18/ich-m-246-chte-f-252-r-typisierte-datasets-eine-lanze-brechen.aspx

@DaFenix: Das kommt davon, wenn man in Eile schnell mal eine Lösung posten möchte. Ist ja fast schon peinlich. Du hast natürlich völlig Recht: Die Sperre muss beim schließen des Dialogs wieder aufgehoben werden.

Ich werde die Fehler schnellsmöglich in meinem Code beheben und eine aktualisierte Version hier posten. Danke für die gemeldeten Bugs!

S
243 Beiträge seit 2005
vor 16 Jahren
trotzdem

beruhigt mich, dass auch du ab und zu mal nen fehler machst 😉

thnx rainbird, hab unglaublich viel gerlernt in der letzten zeit, und am meisten mit deinem app.server beispiel!

D
5 Beiträge seit 2008
vor 15 Jahren

Aus .NET Applikationsserver/Isolierte Dienste
..Ein wichtiges Feature fehlt ++momentan ++noch:Isolierte Ausführung und Konfiguration von DienstenDie einzelnen Dienste laufen derzeit noch nicht isoliert voneinander. Alle Assemblies werden direkt aus dem Anwendungsverzeichnis in die Standard-Anwendungsdomäne des Host-Prozesses geladen. Das macht Schwierigkeiten, wenn verschiedene Versionen des selben Dienstes gleichzeitig betrieben werden sollen. Da man die Standard-Anwendungsdomäne nicht entladen kann, können so im laufenden Betrieb keine Aktualisierungen gefahren werden. Außerdem teilen sich alle Dienste die selbe App.config...

Hallo Rainbird,

wie ist die Herangehensweise um einzelne Dienste während des Betriebes zu aktualisieren bzw. "parallel" zum schon vorhandenen Dienst einen neuen auf dem Applicationserver zu deployen?

Grüße DaFenix

Wer früher stirbt ist länger tot =)

3.728 Beiträge seit 2005
vor 15 Jahren
Anwendungsdomänen

Hallo DeFenix,

die Dienste werden einfach nicht mehr direkt in die Standardanwendungsdomäne geladen, sondern in neue Anwendungsdomänen, die von einer eingezogenen Hosting-Schicht verwaltet werden. Bei einem Update kann die Anwendungsdomäne eines Dienstes entladen werden. Dadurch werden auch alle Assemblies aus dem Speicher entfernt, die in die Anwendungsdomäne geladen waren. Dann werden die Assemblies im Dateisystem aktualisiert und anschließend wird wieder eine neue Anwendungsdomäne erzeugt, in welche die aktualisierten Assemblies geladen werden.

Tatsächlich würde ich mehrere zusammenhängende Dienste zu Anwendungen zusammenfassen. Alle Dienste einer Anwendung hätten ein eigenes Deployment-Verzeichnis, eine eigene Konfiguration und eine eigene Anwendungsdomäne. Das würde den Applikationsserver automatisch auch befähigen, gleichzeitig ganz unterschiedliche Anwendungen zu hosten.

Um im laufenden Betrieb Versionsumstellungen zu machen, ist es etwas aufwändiger. Man muss dabei die neue Anwendungsdomäne für die aktualisierte Version paralell zur bestehenden erzeugen und laden. Dann ist der URI für den Objektaufruf aber immernoch von der alten Version belegt. Um das in den Griff zu bekommen muss man einen generischen Dispatcher schreiben, der den Remoting-URI von der konkreten Dienst-Version abkoppelt. Außerdem müsste man Korrelierungsdaten in den Kontext packen, damit laufende Sitzungen nicht plötzlich eine neue Version untergeschoben bekommen, denn das würde sicher irgendwann knallen.

Diese Features sind aber für dieses Beispiel doch etwas überdimensioniert. Da ich mir aber eh fest vorgenomnmen habe einen ausgewachsenen und quelloffenen Applikationsserver auf WCF-Basis zu schreiben, werden diese Dinge eher dort Einzug halten. WCF hat vielleicht auch schon derartige Ansätze eingebaut, aber da bin ich momentan noch am "forschen". Als Übung werde ich zuerst eine WCF-Version dieses Architekturbeispiels hier schreiben. Das ist dann auch ein schönes Auschauungsobjekt für Leute, die von Remoting auf WCF migrieren wollen.

D
5 Beiträge seit 2008
vor 15 Jahren

Okay, klingt aufwändiger.. danke für die gute Erläuterung.👍

Grüße,
DaFenix

Wer früher stirbt ist länger tot =)

3.728 Beiträge seit 2005
vor 15 Jahren
Bugfix

Hallo,

ich habe die angesprochenen Bugs behoben. Hier gibts die gefixte Version 1.2:
.NET Applikationsserver

B
122 Beiträge seit 2004
vor 15 Jahren

Hallo,

Leider kann ichs mit meiner 2008 nicht kompilieren 🙂

MFG

3.728 Beiträge seit 2005
vor 15 Jahren
Visual Studio-Version

Hallo boonkerz,

ich habe leider nur Visual Studio 2005 Standard und deshalb keine Möglichkeit es mit 2008 zu testen. Wenn man die Ziel-Framework-Version auf 2.0 einstellt, sollte es aber theoretisch auch mit Visual Studio 2008 laufen. Lässt sich die Projektmappe nicht ins neue Format konvertieren?

Die Projektmappe enthält Projektmappenordner. Diese werden von den Express Versionen nicht unterstützt (So war das zumindest bei Visual C# 2005 Express). Was für eine Edition von Visual Studio 2008 verwendest Du?

Welche Fehler zeigt der Compiler denn an?

Falls es bei Dir wirklich an der Kombination Express-Edition und Projektmappenordner liegen sollte, findest Du hier im Anhang eine Version ohne Projektmappenordner.

B
122 Beiträge seit 2004
vor 15 Jahren

Hallo,

Ich kopiere das mal hier einfach rein.
Kommt obwohl das DataSet eigendlich vorhanden ist.

Error 1 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 18 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 2 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 46 65 Rainbird.Examples.NTier.Inventory.Contracts
Error 3 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 46 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 4 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 53 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 5 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 60 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 6 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 67 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 7 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 87 9 Rainbird.Examples.NTier.Inventory.Contracts
Error 8 The type or namespace name 'InventoryDataSet' could not be found (are you missing a using directive or an assembly reference?) C:\rainbird\Rainbird.Examples.NTier.Inventory.Contracts\IInventoryService.cs 98 9 Rainbird.Examples.NTier.Inventory.Contracts

3.728 Beiträge seit 2005
vor 15 Jahren
Version für Visual Studio 2008

Hallo boonkerz,

ich habe nun eine lauffähige Version für Visual Studio 2008. Du findest sie hier: .NET Applikationsserver

1.457 Beiträge seit 2004
vor 15 Jahren
Fragen zur Beispielanwendung...

Hallo Rainbird,

Ich hatte endlich mal Zeit deine Beispielanwendung anzuschauen und habe auch gleich Fragen dazu:

1.) Was ist MSDTC und was genau macht dieser Dienst in deiner Anwendung?
Ich muss ehrlich sagen das ich noch nie mit MSDTC beschäftigt habe und der Wikipedia Artikel mir eigentlich nichts sagt.

Sehe ich das richtig das du es für die ServiceFactory<T>, genauer CreateLocalProxyViaIPC benötigst?

Für was genau wird dieser Dienst in deiner Anwendung benötigt? Könnte man es auch ohne diesen Dienst machen?

2.) Da ich mich mit dem Thema Remoting bis heute nicht intensiv beschäftigt habe, wäre es angebracht zu erfahren ob es möglicht wäre den Applikationsserver auch auf einem gehostet / nicht gehostet Webserver unterzubringen um so sowohl über Web Client als Windows Client zugreifen zu können? Oder doch lieber Web Service?

Vielen Dank im Voraus.

P.S.: Man sieht das man täglich neue Erkenntnisse bzgl. .NET Programmierung bekommen kann. Man lernt eben nie aus 😉

3.728 Beiträge seit 2005
vor 15 Jahren

Hallo burning snow,

gerne beantworte ich Deine Fragen.

1.) Was ist MSDTC und was genau macht dieser Dienst in deiner Anwendung?
Ich muss ehrlich sagen das ich noch nie mit MSDTC beschäftigt habe und der
>
Artikel mir eigentlich nichts sagt.

Der Distributed Transaction Coordintaor ist ein Windows-Dienst, der verteilte Transaktionen verwaltet. Im Unterschied zu RDBMS internen Transaktionen, können sich verteilte Transaktionen auf mehrere verschiedene Server und auch ganz verschiedene Ressourcen erstrecken. So können z.B. INSERT, UPDATE und DELETE Operationen auf verschiedenen Datenbanksystemen innerhalb der selben Transaktion ablaufen. Ein Teil der Operationen könnte z.B. auf einer MS SQL Server und der andere Teil auf einem Oracle Server verarbeitet werden. Trotzdem würde eine verteilte Transaktion sicherstellen, dass entweder alles oder nichts in die zwei ganz verschiedenen Datenbanken geschrieben wird. Da jedes RDBMS eine ganz eigene Transaktions-Implementierung hat, benötigt man einen Koordinator, der den Zustand aller beteiligten Datenbanken kennt und diese veranlasst einen Commit bzw. Rollback für ihre Teil-Transaktion auszuführen. Dieser Koordinator ist seit Windows 2000 ins Betriebssystem eingebaut und heißt MSDTC. Bei Windows NT musste man den MSDTC noch über das Windows NT option Pack nachinstallieren.
Zusammenfassend kann man sagen, dass man den MSDTC-Dienst immer dann benötigt, wenn man den System.Transaction-Namensraum des .NET Frameworks verwendet. Ich verwende in den meisten Fällen immer System.Transaction-Transaktionen, statt die "herkömmlichen" ADO.NET Transaktionen. Der Grund dafür ist die wesentlich bessere Skalierbarkeit. Transaktionen sollen über mehrere Dienste aufgespannt werden können, ohne dass dafür Kenntnis über die gekapselte Datenzugriffslogik einzelner Dienste nötig ist. System.Transactions ermöglicht es einen serialisierbaren - und damit verteilbaren - Transaktionskontext zu erzeugen und diesen an alle Methoden weiterzugeben, die an der Transaktion teilnehmen sollen. Egal mit welcher Datenbank oder sonstiger Ressource ein Dienst redet.
Außerdem kann man auch selber sogenannte Kompensierende Ressourcen-Manager für System.Transactions schreiben, um Ressourcen, wie z.B. das Dateisystem oder eine einfache Hashtable im Speicher, in eine Transaktion miteinzubeziehen.
Damit das alles aber auch korrekt funktioniert, muss der MSDTC-Dienst gestartet und richtig konfiguriert sein. Wichtig sind dabei vor allem die Sicherheitseinstellungen für Remote-Zugriffe. Man sollte auch nicht den Fehler machen, und Transaktionen auf den Clients starten. Das würde nämlich bedeuten, dass der MSDTC auf jedem Client konfiguriert werden muss.

Du findest die Einstellungen für den MSDTC in der Systemsteuerung unter Verwaltung -> Komponentendienste (Siehe Bild im Anhang).

Sehe ich das richtig das du es für die ServiceFactory<T>, genauer CreateLocalProxyViaIPC benötigst?

Nö, der MSDTC wird für verteilte Transaktionen benötigt. CreateLocalProxyViaIPC erzeugt nur einen Proxy zu einem Dienst über den lokalen IPC-Kanal. Das ist dafür gedacht, dass Dienste, die auf dem selben Applikationsserver laufen, sich gegenseitig aufrufen können, ohne über den IP-Stack kommunizieren zu müssen. IPC funktioniert intern mit Named Pipes und ist wesentlich performanten (funktioniert aber nur lokal und nicht über Netzwerk).

Für was genau wird dieser Dienst in deiner Anwendung benötigt? Könnte man es auch ohne diesen Dienst machen?

Man könnte den Applikationsserver auch ohne verteilte Transaktionen verwenden und bräuchte dann natürlich auch keinen MSDTC. Dann könnte man allerdings System.Transactions nicht verwenden und müsste auf Standard-ADO.NET Transaktionen ausweichen. Das kann aber durchaus ausreichend sein. Verteilte Transaktionen sind zwar toll, aber auch aufwändig und werden für kleinere Projekte oft als unnötig oder überdimensioniert empfunden. Wenn der SQL Server 2005 aber die Haupt-Datenbank der Anwendung verwaltet, spielt es nicht wirklich eine Rolle, da System.Transactions den MSDTC dann nur dann verwendet, wenn er wirklich gebraucht wird. Für Transaktionen, die nur auf dem SQL Server laufen, verwendet System.Transaction den Leichtgewichtigen LTM als Transaktions-Koordinator.
Generall kann ich Deine Frage also mit Ja beantworten. Verteilte Anwendungen auf Basis von Remoting brauchen keinen MSDTC.

2.) Da ich mich mit dem Thema Remoting bis heute nicht intensiv beschäftigt habe, wäre es angebracht zu erfahren ob es möglicht wäre den Applikationsserver auch auf einem gehostet / nicht gehostet Webserver unterzubringen um so sowohl über Web Client als Windows Client zugreifen zu können? Oder doch lieber Web Service?

Ich habe mein Architekturbeispiel so entworfen, dass man auch ohne Probleme Webclients mit ASP.NET dafür bauen kann. Ein Anwendungsfall wäre z.B. Intranet/Extranet. Dabei wäre der Applikationsserver nicht von außen zugreifbar, sondern nur der Webserver mit dem ASP.NET Client. Der ASP.NET Client redet per Remoting mit dem Applikationsserver, der sich im selben LAN befindet. So können z.B. lokal komfortable Windows.Forms Clients zum Einsatz kommen und für Geschäftspartner oder reisende Mitarbeiter ein Webclient. Beide Client-Anwendungen würden die selben Dienste nutzen.

So würde sich eine ASP.NET Seite beim Applikationsserver anmelden:


/// <summary>
/// Wird aufgerufen, wenn die Seite geladen wird.
/// </summary>
/// <param name="sender">Herkunftsobjekt</param>
/// <param name="e">Ereignisargumente</param>
protected void Page_Load(object sender, EventArgs e)
{    
    // Wenn es kein Postback ist ...
    if (!IsPostBack)
    {
        // Wenn der Webserver sich erfolgreich am Applikationsserver anmelden konnte ...
        if (ApplicationServer.Logon(Properties.Settings.Default.ServerURL))
        {
            // Applikationsserver Sitzung im Sitzungsstatus speichern
            ApplicationServer.SaveContextDataInWebSessionState(this);
        }
    }
}

Um z.B. bei einem Klick auf einen Button bestimmte Artikel suchen zu lassen und in einem ASP.NET DataGrid anzuzeigen, würde man folgendermaßen vorgehen:


/// <summary>
/// Wird beim klicken auf den Suchen-Knopf ausgeführt.
/// </summary>
/// <param name="sender">Herkunftsobjekt</param>
/// <param name="e">Ereignisargumente</param>
protected void _findProductNoButton_Click(object sender, ImageClickEventArgs e)
{
    // Suchkriterien/Suchmuster aus ASP.NET-Textbox lesen
    string pattern = _findProductNoBox.Text;

    // Applikationsserver-Kontext aus ASP.NET-Sitzungsstatus wiederherstellen
    ApplicationServer.LoadContextDataFromWebSessionState(this);

    // Verbinding zum Artikelverwaltungsdienst herstellen
    IArticleMasterService proxy = ServiceFactory<IArticleMasterService>.CreateProxy();
    
    // Produkte anhand der Produktnummer suchen
    DataTable result=proxy.FindProductsByNumber(pattern);

    // Suchergebnisse anzeigen
    _grid.DataSource = result;
    _grid.DataBind();
}     

Es ist im Vergleich zum Windows.Forms-Client nur eine Zeile Code mehr erforderlich. Da HTTP statuslos ist, muss der Applikationsserver-Sitzung immer in eine ASP.NET Sitzungsvariable geschrieben und auch wieder herausgeholt werden. Dies erledigen die Methoden SaveContextDataInWebSessionState und LoadContextDataFromWebSessionState.

Auf einem gehosteten Webserver sehe ich keine Einsatzmöglichkeit für mein Architekturbeispiel. Da würde ich eher zu WCF greifen. ASP.NET Webservices würde ich nicht verwenden, da dort die Sicherheit zu wünschen übrig lässt. Außer Transportsicherheit mit SSL herrscht nämlich gähnende Leere.

Ich muss noch anmerken, dass mein Beispiel momentan nur mit Windows-Authentifizierung funktioniert. Ein unangenehmer Nebeneffekt ist, dass man den Applikationsserver neu starten muss, wenn sich Gruppenmitgliedschaften ändern, damit diese auch korrekt als Rollen verwendet werden. Aber es ist ja such "nur" ein Beispiel. Mit relativ wenig Aufwand könnte man ein Datenbank gestütztes Rollensystem einbauen. Da es aber in erster Linie ein Beispiel ist, war mir das zu aufwändig.

Hast Du ein konkretes Projekt, bei dem Du Remoting einsetzen willst?

1.457 Beiträge seit 2004
vor 15 Jahren

Hallo Rainbird,

Vielen Dank für deine Antwort.

Bzgl. des ASP.NET Clients:

Bei meiner Anwendung würde es zwar so funktionieren wie du es beschrieben hast, nur habe ich auch einen weiteren Kunden der diese Applikation auf einem ASP.NET Webserver benutzen möchte. Also ohne Windows Forms Client.

Hier würde das Konzept des App.-Servers dann nicht mehr reinpassen obwohl die Anwendung mit und ohne App.-Server laufen soll.

Wenn ich deine Beispielanwendung richtig interpretiert habe, müsste ich die ServiceFactory<T> dementsprechend ändern, dass der Zugriff, je nach Konfiguration, über Remoting oder über die Assemblies läuft.

Was meinst du?

X
1.177 Beiträge seit 2006
vor 15 Jahren

Hallo Rainbird,

ich stolper zwar alle paar Wochen über deinen App-Server, hab aber heute Abend endlich mal die Zeit gefunden die Diskussion zu lesen^^

Zum Thema Skalierbarkeit und Sessions - welche ja ganz am Anfang angesprochen wurden. Hier ergibt sich eine recht einfache und extrem skalierbare Lösung.

Wenn die Session immer im Client behandelt wird, so setzte man einfach einen Loadbalancer vor die Serverphalanx mit den Servern mit Appserver (der LB kann als Sessionlos laufen, Kosten unter 2000€) - damit behandelt man dann 20 Server und wehe einer behauptet das reicht nicht. Im Normalfall ist dann eher der Netzwerkdurchsatz die Schwachstelle.

Sessions im Server: hier fehlt dann ja noch ein Session-Handling. Dies wird aber bei allen (App-) Server-Umgebungen mit Bedacht betrachtet. Man könnte alle Sessions immer zwischen den Servern tauschen (=Speicher-lastig, Netzwerk: nimm ein Backbone mit 1GB und kein Prob) oder in einer DB halten (=langsamer, aber immer im Zugriff) und diese DB per Mirror auf einen 2. Server spiegeln. Sessions immer als Objekte per [Serializable] festhalten (bei Aufruf laden, dannach serialisieren auf DB oder per Multicast auf alle anderen Server, stellt sich die Frage ob Binary-Serialization das Attribut benötigt? ASP kann das ja auch mit allem)

Insofern denke ich nicht dass deine kleine, feine Umgebung damit Probleme haben würde.

Zu App-Servern im Allgemeinen: mir fehlt immer die Möglichkeit - welche ja schon viele hier diskutierte Projekte haben - einfach ein Plugin mit gewissen Funktionen (z.b. Session für Appserver, SOAP-Kommunikation (Webservice), Authentifizierung (LDAP, intern perDB)) dazu zu binden. Das bedeutet für mich: das Ding ist Leichtgewichtig und tut nur dass was ich dann auch Kontrollieren kann. Es gibt einige grosse Applikationen und Server, aber allen ist gemein dass man sie nicht kontrollieren kann. Alle haben irgendwelche Schnittstellen oder Sinks in die man was einhängen kann, aber das ist immer in gewisserweise mit Einarbeitungszeit verbunden (z.b. - SQL-Server: brauch ich echt alles was da installiert wird, Exchange: klar ein vb-script in einen SMTP-Sink einhängen ist cool, aber was soll dass? Warum gibt es bei Remoting nicht einfach ein Plugin-Interface ohne dass man die App-Config bearbeiten muss??)

Zwar mag jetzt jemand einwenden, dass JBOSS (oder sonst ein Produkt) dass ja alles könnte, aber ich bin Entwickler und will schnell und easy eine Lösung (ala Scotty: Wiel lang brauchst Du? 2 Monate - ich geb Dir 2 Wochen, Ok, ich machs in 2 Tagen)

Insofern, jo, ein schlanker schneller Ansatz. Das benötigte sollte jeder selbst hinbekommen.

🙂

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

3.728 Beiträge seit 2005
vor 15 Jahren

Hallo Rainbird,
Bei meiner Anwendung würde es zwar so funktionieren wie du es beschrieben hast, nur habe ich auch einen weiteren Kunden der diese Applikation auf einem ASP.NET Webserver benutzen möchte. Also ohne Windows Forms Client.

Doch doch das geht. Der Applikationsserver und die Dienste sind völlig unabhängig vom Windows.Forms-Client. Man könnte statt des Windows.Forms-Clients auch nur einen ASP.NET-Webclient haben. Der Webclient auf dem IIS redet dann über TCP/IP mit dem Applikationsserver. Solange der ASP.NET Webclient inhouse gehostet wird und sich im selben LAN Segment mit dem Applikationsserver befindet, ist das gar kein Problem. Blöd wird es nur, wenn der Applikationsserver inhouse und der Webserver beim Provider steht. Dann ist der Lösungsansatz wirklich nicht passend. Wenn man beim Provider einen Root-Server gemietet hat, kann man App.-Server und Webserver beide dort betreiben. Bei gehostetem Webspace hat man meistens keine Möglichkeit einen eigenen Windows-Dienst auf dem Server zu deployen.

Wenn ich deine Beispielanwendung richtig interpretiert habe, müsste ich die ServiceFactory<T> dementsprechend ändern, dass der Zugriff, je nach Konfiguration, über Remoting oder über die Assemblies läuft.

Ja, sowas könnte man nachrüsten.

3.728 Beiträge seit 2005
vor 15 Jahren
Modulare leichte Server

Hallo Xynratron,

freut mich, dass Du Dich dafür interessierst.

Wenn die Session immer im Client behandelt wird, so setzte man einfach einen Loadbalancer vor die Serverphalanx mit den Servern mit Appserver (der LB kann als Sessionlos laufen, Kosten unter 2000€) - damit behandelt man dann 20 Server und wehe einer behauptet das reicht nicht. Im Normalfall ist dann eher der Netzwerkdurchsatz die Schwachstelle.

Ich versuche grundsätzlich, auf der serverseite so statuslos wie möglich zu arbeiten. Die einfache Sitzungsverwaltung in meinem Architekturbeispiel wird nur benötigt, um die Identität des ursprünglichen Aufrufers bei verketteten Dienstaufrufen (Client -> Service A -> Service B) abfragen zu können.

Sessions im Server: hier fehlt dann ja noch ein Session-Handling.

Es gibt schon eine Sitzungsverwaltung, aber Sitzungen können nicht auf mehrere Applikationsserver repliziert oder in einer DB persistent gemacht werden.

Dies wird aber bei allen (App-) Server-Umgebungen mit Bedacht betrachtet. Man könnte alle Sessions immer zwischen den Servern tauschen (=Speicher-lastig, Netzwerk: nimm ein Backbone mit 1GB und kein Prob) oder in einer DB halten (=langsamer, aber immer im Zugriff) und diese DB per Mirror auf einen 2. Server spiegeln. Sessions immer als Objekte per [Serializable] festhalten (bei Aufruf laden, dannach serialisieren auf DB oder per Multicast auf alle anderen Server, ...

Wenn die Sessions klein sind (und das werden sie bei mir immer sein) würde ich dazu tendieren, Sessions zwischen den Applikationsservern eines Verbundes zu replizieren. Man muss ja nur die Sessions übertragen, die sich ändern.

Zu App-Servern im Allgemeinen: mir fehlt immer die Möglichkeit - welche ja schon viele hier diskutierte Projekte haben - einfach ein Plugin mit gewissen Funktionen (z.b. Session für Appserver, SOAP-Kommunikation (Webservice), Authentifizierung (LDAP, intern perDB)) dazu zu binden. Das bedeutet für mich: das Ding ist Leichtgewichtig und tut nur dass was ich dann auch Kontrollieren kann.

So ähnlich würde ich mir einen optimalen Anwendungsserver auch vorstellen. Mein kleines Architekturbeispiel kann das natürlich nicht leisten, aber es ist ja auch nur ein Beispiel. Trotzdem denke ich, dass Modularität in Verbindung mit Einfachheit das ist, was momentan bei der Entwicklung von Verteilten Anwendungen fehlt. Es muss einfach sein, seine Komponenten auf dem Applikationsserver laufen zu lassen. Man darf sich nicht erst durch einen Jungel von Konfigurationsdateien kämpfen müssen. Ich mag z.B. das Plug-In System von Photoshop. Man kopiert ein Plug-In einfach in ein bestimmtes Verzeichnis und beim nächsten Start von Photoshop wird es automatisch geladen. Keine Registry, kein Setup, keine Konfigurationsdateien. In der Art möchte ich auch meine Komponenten auf den Applikationsserver bringen.

Warum gibt es bei Remoting nicht einfach ein Plugin-Interface ohne dass man die App-Config bearbeiten muss??

Remoting ist eben kein Produkt, sondern nur ein leichtgewichtiges Kommunikations-API. Es fehlt der leistungsfähige generische Host. Genauso wie er bereits bei COM+ gefehlt hat. Der IIS ist nicht die Lösung. Daran ändert auch der WAS nichts. Es muss viel einfacher werden Komponenten auf Server-Computern zu verteilen, dort laufen zu lassen und man muss diese auch mit vertretbarem Aufwand warten und updaten können.

S
243 Beiträge seit 2005
vor 15 Jahren

Ich kann mich auch täuschen, aber war da nicht bei einer früheren Version auch wein Web-Client dabei? Sogar mit Webservice der von Win- als auch Web-Client genutzt wird?! Oder täusch ich mich da jetzt total ...

hab sogar folgendes in einem anderen post von dir gefunden, rainbird:
_
Momentan sind folgende Erweiterungen in Arbeit oder zumindest geplant:
Eine vollständige ASP.NET Weboberfläche

Eine Version, die statt Remoting WCF als Kommunikationstechnologie verwendet

Gruppierung von Diensten in Applikationen (Pro Applikation eine eigene AppDomain)_

3.728 Beiträge seit 2005
vor 15 Jahren
Weiterentwicklung des Architekturbeispiels

Hallo spidermike,

es war noch kein Webclient dabei. Aber die API unterstützt bereits ASP.NET. In folgendem Beitrag wird beschrieben, wie man bei einem ASP.NET Client vorgeht: Hier klicken

Ich habe noch nicht die Zeit gefunden, einen vollständigen Webclient zu schreiben.

Momentan beschäftige ich mich mit WCF. Das ist viel umfangreicher als gedacht. Deshalb ist die WCF-Version auch noch nicht fertig.

Die Isolierung verschiedener Anwendungen auf einem Host voneinander wird in dieses Beispiel wohl nicht mehr einfließen. Es ist einfach zu viel Aufwand und würde das Architekturbeispiel so verkomplizieren, dass Einsteiger ins Thema damit nichts mehr anfangen könnten. Das ist eher was für richtiges .NET Application Server Produkt, welches man als fertige Platform für seine Anwendungen einsetzt. Sowas sollte aber unbedingt auf WCF aufgebaut sein.

Q
204 Beiträge seit 2005
vor 15 Jahren
Fehlermeldung

Hi Leute,

ich möchte hier diesen Thread nocheinmal aufrollen.
Habe mir den Applicationsserver angesehen und mal ein bisschen rumprobiert.
Zuerst habe ich diesen nicht einmal zum laufen gebracht, das hat sich jetzt erledigt.
Warum auch immer????????????

aber egal was ich jetzt mach, ich bekomme immer eine Fehlermeldung die wie
folgt aussieht -> siehe Anhang
Vielleicht kann mir das jemand erklären oder weiterhelfen.

Danke im voraus

3.728 Beiträge seit 2005
vor 15 Jahren
Dienst nicht gefunden

Hallo Qt21580,

anscheinend versuchst Du einen Dienst aufzurufen, der nicht oder nicht korrekt vom Anwendungsserver bereitgestellt wird. Häufigste Ursache sind vergessene Einträge im <Services>-Bereich der App.config des Servers, oder Tippfehler in diesem Bereich.

Wie sieht die Implementierung Deines UserService aus?

Q
204 Beiträge seit 2005
vor 15 Jahren
Fehlende Datei oder Assembly

Das mit dem Service in der app.config stimmte,
habe diese Zeile vergessen aber dafür bekomme ich jetzt eine neue FileNotFoundException?????????????

Auschnitt aus der config datei
<service>
<!-- Geschäftsdienst "Userverwaltung" -->
<wellknown mode="SingleCall" type="EBMS.Users.Services.UserService, EBMS.Users.Services" objectUri="EBMS.Users.Contracts.IUserService" />
<!-- Geschäftsdienst "Artikelstammverwaltung" -->
<!--wellknown mode="SingleCall" type="Rainbird.Examples.NTier.ArticleMaster.Services.ArticleMasterService, Rainbird.Examples.NTier.ArticleMaster.Services" objectUri="Rainbird.Examples.NTier.ArticleMaster.Contracts.IArticleMasterService" /-->
<!-- Geschäftsdienst "Lagermverwaltung" -->
<!--wellknown mode="SingleCall" type="Rainbird.Examples.NTier.Inventory.Services.InventoryService, Rainbird.Examples.NTier.Inventory.Services" objectUri="Rainbird.Examples.NTier.Inventory.Contracts.IInventoryService" /-->
</service>

3.728 Beiträge seit 2005
vor 15 Jahren
Deployment

Du musst die Assembly EBMS.Users.Services.dll und alle abhängigen Assemblies ins Ausführungsverzeichnis des Applikationsservers kopieren. Die Contract-Assembly EBMS.Users.Contracts.dll muss zusätzlich beim Client als Verweis zugefügt werden.

Du kannst diese Datei-Kopier-Arbeiten idealerweise als Post Build Script in Visual Studio anlegen, dann musst Du das nicht immer von Hand machen.

Außerdem ist es wichtig, dass die Contract-Assemblies auf den Clients und auf dem Server in der selben Version vorliegen. Wenn Du neue Versionen auf dem Applikationsserver deployst, müssen auch alle Clients aktualisiert werden.

Q
204 Beiträge seit 2005
vor 15 Jahren

Danke Rainbird,

jetzt funkt's

N
52 Beiträge seit 2008
vor 15 Jahren

Hallo Rainbird,

erstmal danke für die tolle Demo - habe mich heute mal etwas gespielt damit.

Nun eine kurze Frage dazu: Wir haben vor für unsere Anwendung auch einen Server zu "basteln", vorallem um Windows Forms und natürlich auch Web Zugriff mittels ASP zu ermöglichen.

Dein Beispiel gefällt mir sehr gut, die Frage ist sollte man auf diese Technik bauen oder eher schon auf WCF gehen?

Danke

3.728 Beiträge seit 2005
vor 15 Jahren
Remoting oder WCF

Dein Beispiel gefällt mir sehr gut, die Frage ist sollte man auf diese Technik bauen oder eher schon auf WCF gehen?

Das kommt darauf an, was man vor hat. Alles was in Richtung Internet-Kommunikation geht oder vielleicht mal gehen könnte, würde ich gleich mit WCF bauen. Auch wenn es um Interoperabilität mit anderen Plattformen geht, würde ich kein Remoting verwenden.
Wenn aber "nur" .NET Komponenten einer Anwendung übers LAN kommunizieren sollen, ist Remoting ideal. Es ist sehr viel weniger komplex als WCF und ist damit leichter erlern- und auch beherrschbar. Außerdem ist es ausgereift und die Macken sind bekannt und überall nachzulesen.

Man kann die Architektur meines Beispiels im Groben auch mit WCF umsetzen.

N
52 Beiträge seit 2008
vor 15 Jahren

Internet-Komminukation bedeutet bei dir auch WebFroms bzw. ASP Zugriff auf die Applikation?

699 Beiträge seit 2007
vor 15 Jahren

Hi zusammen,

ich habe mal eine Frage zu der Ablaufverfolgung, was Rainbird in seinem App-Server einsetzt.

Wo speichert der derzeit die Ausgaben hin? Oder ist das in dem Beispiel nur für die Ausgabe an der Konsole geschrieben?

Bin gerade dabei die App-Server Consolen Anwendung in eine WinForm Anwendung zu migrieren, was soweit auch schon klappt.
Nur möchte ich die Ablaufverfolgung in einem textBox Object anzeigen lassen ( Das ist jetzt nicht meine frage, sondern nur eine Info was ich gerade versuche. Habe da schon meine Idee gefunden, wie ich das realisieren kann. ).

Ansonsten ist das Beispiel von Rainbird ja relativ einfach nachvollziehbar.

Grüße Stephan

3.728 Beiträge seit 2005
vor 15 Jahren
Internet Kommunikation

Internet-Komminukation bedeutet bei dir auch WebFroms bzw. ASP Zugriff auf die Applikation?

Mit Internet-Kommunikation im Zusammenhang mit verteilten Anwendungen meine ich, dass Applikationsserver und Clients über das Internet kommunizieren. Clients können dabei klassische Windows-Anwendungen oder auch Web-Anwendungen, wie z.B. ASP.NET Webseiten auf einem WebServer sein.

Mein Architektur-Beispiel sieht vor, dass der Applikationsserver mit dem Webserver im selben LAN laufen. Ob der Webserver nun in Richtung Internet offen ist, oder nicht, spielt für die Architektur eigentlich keine Rolle.

ASP.NET Seiten sind mit Windows.Forms-Anwendungen gleichzusetzen. Sie gehören zur Präsentationsschicht und implementieren die Benutzeroberfläche. Deshalb stellt sich die Frage, ob der Applikationsserver auf ASP.NET Anwendungen zugreift eigentlich gar nicht. Die Geschäftslogik greift niemals auf Elemente der Präsentationsschicht zu. Manche Leute kommen durcheinander, weil bei Webanwendungen die Darstellung auf einem Server erzeugt wird.

3.728 Beiträge seit 2005
vor 15 Jahren

ich habe mal eine Frage zu der Ablaufverfolgung, was Rainbird in seinem App-Server einsetzt.

Wo speichert der derzeit die Ausgaben hin? Oder ist das in dem Beispiel nur für die Ausgabe an der Konsole geschrieben?

Hallo Stipo,

ich verwende die Standard Ablaufverfolgungs-Technologie vom .NET Framework aus dem System.Diagnostics-Namensraum. Die Ablaufverfolgung wird komplett über die App.config konfiguriert. Vorteil dabei ist, dass ich die Ablaufverfolgung komplett ändern kann, ohne meinen Applikationsserver neu kompilieren zu müssen. Du findest die Einstellungen alle dokumentiert in der App.config des Projekts Rainbird.AppServer. Für die verschiedenen Teile der Anwendungen habe ich sogenannte Trace Switches (Ablaufverfolgungs-Schalter) definiert. Diese lassen sich per App.Config ein- und ausschalten. Pro Trace Switch können beliebig viele Trace Listener festgelegt werden. Diese nehmen die Trace Meldungen auf, formatieren sie entsprechend und geben schreiben sie auf das Ziel-Medium. Standardmäßig ist ein ConsoleTraceListener aktiv, der alle Trace-Meldungen auf die Konsole schreibt. Man könnte aber ohne Probleme per App.config einen zusätzlichen Trace Listener konfigurieren, der z.B. statt auf die Konsole in ein Log-File schreibt. Das währe dan z.B. ein LogFileTraceListener. Du könntest aber auch einen eigenen Trace Listener schreiben, welcher die Trace-Informationen an Deine Windows-Anwendung sendet.

Hier der Trace-Bereich der App.config:

      <!-- Applikationsserver-Kern -->
      <source name="Core" switchName="CoreSwitch">
        <listeners>
          <!-- Standard Ablaufverfolgungsempfänger aus dieser Quelle entfernen -->
          <remove name="Default" />
          <!-- Gemeinsam genutzten Konsolen-Ablaufverfolgungsempfänger dieser Quelle zufügen -->
          <add name="SharedConsoleTraceListener" />
          <!-- Gemeinsam genutzten Protokolldatei-Ablaufverfolgungsempfänger dieser Quelle zufügen -->
          <!--<add name="SharedLogFileTraceListener" />-->
        </listeners>
      </source>
699 Beiträge seit 2007
vor 15 Jahren

Hallo Stipo,

ich verwende die Standard Ablaufverfolgungs-Technologie vom .NET Framework aus dem System.Diagnostics-Namensraum. Die Ablaufverfolgung wird komplett über die App.config konfiguriert. Vorteil dabei ist, dass ich die Ablaufverfolgung komplett ändern kann, ohne meinen Applikationsserver neu kompilieren zu müssen. Du findest die Einstellungen alle dokumentiert in der App.config des Projekts Rainbird.AppServer. Für die verschiedenen Teile der Anwendungen habe ich sogenannte Trace Switches (Ablaufverfolgungs-Schalter) definiert. Diese lassen sich per App.Config ein- und ausschalten. Pro Trace Switch können beliebig viele Trace Listener festgelegt werden. Diese nehmen die Trace Meldungen auf, formatieren sie entsprechend und geben schreiben sie auf das Ziel-Medium. Standardmäßig ist ein ConsoleTraceListener aktiv, der alle Trace-Meldungen auf die Konsole schreibt. Man könnte aber ohne Probleme per App.config einen zusätzlichen Trace Listener konfigurieren, der z.B. statt auf die Konsole in ein Log-File schreibt. Das währe dan z.B. ein LogFileTraceListener. Du könntest aber auch einen eigenen Trace Listener schreiben, welcher die Trace-Informationen an Deine Windows-Anwendung sendet.

Hallo Rainbird,

danke für die Detailierte Infos zu dem TraceListener Objekt. Aber ich muss gestehen, das ich mittlerweile schon drauf gekommen bin wie der Funktioniert 😉

Aber ich denke mal die Infos hier, können auch anderen noch helfen, wenn sie auch mal vor dem Thema stehen 😉

Ich habe den TraceListener auch schon auf meine bedürfnisse erweitert, indem ich eine eigene TraceListener Klasse erstellt habe, welche mir die ausgaben in eine List<T> schreibt, die ich dann nach belieben in meiner GUI abfragen kann 🙂 Hier mal noch der Link zu meinem eigenen TraceListener

Grüße Stephan