Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Fragen, Diskussion, Kritik zu Projekt ".NET Applikationsserver"
spidermike
myCSharp.de - Member



Dabei seit:
Beiträge: 245

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
Blogscreen
myCSharp.de - Member

Avatar #avatar-2764.gif


Dabei seit:
Beiträge: 389
Herkunft: Stuttgart

beantworten | zitieren | melden

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.
:baby:-> :]-> 8o->
private Nachricht | Beiträge des Benutzers
Tokka
myCSharp.de - Member



Dabei seit:
Beiträge: 108
Herkunft: Hamburg

beantworten | zitieren | melden

@RPlaner: Es tut mir leid, aber mir bleibt der Sinn verschlossen, was Dein Problem mit dem Applicatin Server von Rainbird zu tun haben.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Tokka am .
Was einmal war, wird nie wieder sein...
private Nachricht | Beiträge des Benutzers
Blogscreen
myCSharp.de - Member

Avatar #avatar-2764.gif


Dabei seit:
Beiträge: 389
Herkunft: Stuttgart

beantworten | zitieren | melden

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

Sry
:baby:-> :]-> 8o->
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Neue Version des Beispiels

beantworten | zitieren | melden

Hallo,

es gibt unter .NET Applikationsserver eine neue Version des n-Tier Architekturbeispiels.
private Nachricht | Beiträge des Benutzers
DaFenix
myCSharp.de - Member



Dabei seit:
Beiträge: 5

beantworten | zitieren | melden

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 =)
private Nachricht | Beiträge des Benutzers
[email protected]
myCSharp.de - Member



Dabei seit:
Beiträge: 237

beantworten | zitieren | melden

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 ?
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Bugs

beantworten | zitieren | melden

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();
    }
}

@[email protected]: 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?
private Nachricht | Beiträge des Benutzers
[email protected]
myCSharp.de - Member



Dabei seit:
Beiträge: 237

beantworten | zitieren | melden

Zitat von Rainbird
@[email protected]: 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.
private Nachricht | Beiträge des Benutzers
DaFenix
myCSharp.de - Member



Dabei seit:
Beiträge: 5

beantworten | zitieren | melden

Zitat von Rainbird
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);
}
}
}
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von DaFenix am .
Wer früher stirbt ist länger tot =)
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Bugs, Bugs, Bugs

beantworten | zitieren | melden

@[email protected]: 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!
private Nachricht | Beiträge des Benutzers
spidermike
myCSharp.de - Member



Dabei seit:
Beiträge: 245

trotzdem

beantworten | zitieren | melden

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!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von spidermike am .
private Nachricht | Beiträge des Benutzers
DaFenix
myCSharp.de - Member



Dabei seit:
Beiträge: 5

beantworten | zitieren | melden

Zitat
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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von DaFenix am .
Wer früher stirbt ist länger tot =)
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Anwendungsdomänen

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
DaFenix
myCSharp.de - Member



Dabei seit:
Beiträge: 5

beantworten | zitieren | melden

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

Grüße,
DaFenix
Wer früher stirbt ist länger tot =)
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Bugfix

beantworten | zitieren | melden

Hallo,

ich habe die angesprochenen Bugs behoben. Hier gibts die gefixte Version 1.2:
.NET Applikationsserver
private Nachricht | Beiträge des Benutzers
boonkerz
myCSharp.de - Member



Dabei seit:
Beiträge: 122

beantworten | zitieren | melden

Hallo,

Leider kann ichs mit meiner 2008 nicht kompilieren

MFG
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Visual Studio-Version

beantworten | zitieren | melden

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.
Attachments
private Nachricht | Beiträge des Benutzers
boonkerz
myCSharp.de - Member



Dabei seit:
Beiträge: 122

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Version für Visual Studio 2008

beantworten | zitieren | melden

Hallo boonkerz,

ich habe nun eine lauffähige Version für Visual Studio 2008. Du findest sie hier: .NET Applikationsserver
private Nachricht | Beiträge des Benutzers
Timur Zanagar
myCSharp.de - Member

Avatar #avatar-3412.jpg


Dabei seit:
Beiträge: 1559

Fragen zur Beispielanwendung...

beantworten | zitieren | melden

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 ;-)
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

beantworten | zitieren | melden

Hallo burning snow,

gerne beantworte ich Deine Fragen.
Zitat von burning snow
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.
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).
Zitat von burning snow
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).
Zitat von burning snow
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.
Zitat von burning snow
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?
Attachments
private Nachricht | Beiträge des Benutzers
Timur Zanagar
myCSharp.de - Member

Avatar #avatar-3412.jpg


Dabei seit:
Beiträge: 1559

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
Xynratron
myCSharp.de - Member



Dabei seit:
Beiträge: 1184

beantworten | zitieren | melden

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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Xynratron am .
Herr, schmeiss Hirn vom Himmel - Autsch!
Zitat von herbivore
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

beantworten | zitieren | melden

Zitat von burning snow
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.
Zitat von burning snow
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.
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Modulare leichte Server

beantworten | zitieren | melden

Hallo Xynratron,

freut mich, dass Du Dich dafür interessierst.
Zitat von Xynratron
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.
Zitat von Xynratron
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.
Zitat von Xynratron
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.
Zitat von Xynratron
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.
Zitat von Xynratron
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.
private Nachricht | Beiträge des Benutzers
spidermike
myCSharp.de - Member



Dabei seit:
Beiträge: 245

beantworten | zitieren | melden

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)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von spidermike am .
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Weiterentwicklung des Architekturbeispiels

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Qt21580
myCSharp.de - Member



Dabei seit:
Beiträge: 204

Fehlermeldung

beantworten | zitieren | melden

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
Attachments
private Nachricht | Beiträge des Benutzers
Rainbird
myCSharp.de - Experte

Avatar #avatar-2834.jpg


Dabei seit:
Beiträge: 3953
Herkunft: Mauer

Dienst nicht gefunden

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers