DevTrain

Autor: Tobi Ulm

Remoting in Microsoft .net -- Teil II

Willkommen zum zweiten Teil unserer Exkursion in das Remoting Framework des Microsoft .net Frameworks. Im ersten Teil haben wir uns um grundlegende Begriffe gekümmert und ein erstes Beispiel für Remoting umgesetzt. Dabei haben wir die eigentliche Funktionalität in Form eines .net Assemblies codiert und diese dann durch eine ganz einfache Konsolen Anwendung zum "anfassen" durch einen Windows Client gebracht. Wir sind dabei so vorgegangen, dass wir die .net Komponente auf einen TCP Port gelegt haben und das Objekt als "WellKnownObject" auf dem Server registriert haben. Ausserdem haben wir den ganz normalen Binary Formatter verwendet, der standardmässig zum Einsatz kommt, wenn wir über TCP gehen. Heute will ich Ihnen ein weiteres Highlight (wenn nicht sogar DASS Highlight) des Remoting .net Frameworks zeigen. Wenn Sie sich erinnern habe ich im ersten Teil darauf hingewiesen, dass es zwei Serialization Formatter gibt. Ausserdem empfehle ich Ihnen an dieser Stelle eine kurze Pause zu machen und sich das Beispiel zum "Marshaling" aus dem vorhergegangen Part 1 anzusehen.

 

Übersicht Remoting mit dem SOAP Formatter

Aus dem Bild wird Ihnen vielleicht schon ersichtlich woraus der Hauptvorteil des Remotings mit dem SOAP Formatter besteht, nämlich mit der Unabhängigkeit der Clients. Sobald eine Clientplattform XML und SOAP unterstützt können diese Remotingaufrufe auf ein .net Remoting Objekt machen.

 

 

.net Remoting mit dem SOAP Formatter oder WebServices für "harte Brezn"

Kernpunkt für diese Thematik sind die HttpChannel Klasse aus dem .net Framework. Diese Klasse selbst besteht aus zwei weiteren Klassen den HttpServerChannel und dem HttpClientChannel. Der HttpServerChannel kann jedoch im Gegensatz zum HttpClientChannel auch Binary Remote Streams verstehen. Diese zwei Channels also sind die Leitung über die Remote Anfragen in Form von SOAP Nachrichten verschickt werden. Alle Nachrichten die abgesendet werden durch den SOAP Formatter geschickt und dieser wandelt die Messages in plain XML Streams um und fügt notwendige SOAP Header Informationen hinzu. Als erstes werde ich an dieser Stelle die Serverseitige Funktionalität in Form eines .net Assemblies implementieren. Die Funktionalität dieses Assemblies sei dahingestellt. Es geht nur um den Vorführeffekt.

using System;

using System.Runtime.Remoting;

namespace myRemoteService

{

/// <summary>

/// Beispiel Remote Dienst

/// </summary>

public class myRemoteObject : MarshalByRefObject

{

public myRemoteObject()

{

//

// TODO: Add constructor logic here

//

}

public string myRemoteMethod(string s)

{

return "Hallo " + s;

}

}

 

Wichtig ist an dieser Stelle natürlich auch wieder der Verweis auf das .net Remoting Framework und das Ableiten der Klasse von MarshalByRefObject um eine Referenz übergeben zu können. Danach implementiere ich eine einfache Methode Namens myRemoteMethod(). Ich kompiliere das ganz in ein .net Assembly (.dll). Und jetzt kommt?s:

 

Hosten von Remote Objekten

Es gibt zwei grundlegende Möglichkeiten in der .net Remoting Welt um Remoting Objekte zu hosten. Eine haben sie bereits kennengelernt, nämlich das Hosten in einer Server Executable. Das ist wie bereits erwähnt nicht gerade der Stein der Weisen, also folglich sollte man ein solches Remoting Objekt in Form eines Windows Services hosten. Eine zweite Möglichkeit besteht darin die (oder das) Remoting Objekt(e) in einer ".NET Component Services" Anwendung zu hosten (COM+ Anwendung) und die daraus resultierenden Vorteile zu nutzen (Objekt Pooling, Transaktionen, usw.). Und nun zur dritten und letzten Möglichkeit ( meiner Meinung nach eine sehr nette Möglichkeit), nämlich das Hosten einer solchen Remote Anwendung als Internet Information Services Anwendung (IIS). Das besondere daran ist, das das .net Assembly als WebService veröffentlicht werden kann. Folgende Vorgehensweise müssen Sie dabei beachten:

1. Erzeugen Sie ein virtuelles Verzeichnis (unterhalb des IIS Root's)

2. Das Assembly muss in einem bin Verzeichnis unterhalb des Roots Ihres Virtuellen Verzeichnisses liegen.

3. Es muss ein Konfigurationsfile mitveröffentlicht werden, in dem der Name der Anwendung und die Einstellungen des RemoteObjektes definiert werden.

 

Sollten Sie auf dem Server (IIS) ausserdem ASP.NET verwenden, können sie die Konfiguration auch in dem EventHandler für Application_Start() per Global.asax vornehmen.

Sample:

 

void Application_Start()

{

   IDictionary props = new Hashtable();

   props["name"] = "MeinChannel";

   props["priority"] = "100";

   // Null Einträge spezifizieren die Default Formatter

   HttpChannel channel = new HttpChannel(

      props,

      null,

      null

   );

   ChannelServices.RegisterChannel(channel);

   WellKnownServiceTypeEntry WKSTE = new WellKnownServiceTypeEntry(

      typeof(myRemoteService.myRemoteObject, SimpleRemotingServerObject),

      "myRemoteMethod",

      WellKnownObjectMode.SingleCall

   );

   RemotingConfiguration.RegisterWellKnownServiceType(WKSTE);

}

Sie sollten ausserdem beachten das in dem Konfigurationsfile der Name der Anwendung gleich dem Namen des Virutellen Verzeichnisses ist.

 

 

Die Konfigurationsdateien

Die Konfigurationsdateien machen eigentlich nichts anderes als wir es bereits im ersten Teil des Remoting Tutorials gemacht haben. Es wird das Objekt am Server registriert, die Aktivierungseigenschaften werden bestimmt und das Objekt auf einem bestimmten Port gelegt (zuvor wird natürlich der Port eingerichtet). Also werden in der Konfigurationsdatei die Basis Informationen über Ihr Remoting Objekt gespeichert. Bei einem Remoting Objekt das im IIS gehosted wird sind folgende Punkte jedoch zu beachten:

- Das Konfigurationsfile heisst Web.Config und muss im Root des Virtuellen Verzeichnisses liegen.

- Es kann kein Anwendungsname angegeben werden, des wird automatisch der Name des Virtuellen Verzeichnisses als Anwendungsname benutzt

Ausserdem sind folgende Web.config Elemente nicht zulässig die Sie aus einer ASP.net Anwendung kennen:

- <debug>

- <client>

Und Sie können keinen spezifischen Port festlegen, da wir über den Standardport des WebServers gehen und der ist normalerweise 80. Sollten Sie jedoch das dringende Bedürfnis nach einem speziellem Port haben, so setzten Sie den Port über die Microsoft Management Console for IIS und der Eigenschaftenseite für Ihr Virtuelles Verzeichnis fest.

Sample Web.Config Konfigurationsfile:


 

<configuration>
  <system.runtime.remoting>
    <application>
      <service>
        <wellknown mode="SingleCall" type="myRemoteService.myRemoteObject, SimpleRemotingServerObject" objectUri="SimpleRemotingServerObject.soap" />
      </service>
    </application>
  </system.runtime.remoting>
</configuration>

Das Element <configuration> steht für das Root Element aller Anwendungen in .net

Das Element <System.Runtime.Remoting> beinhaltet Informationen über das Remoting Objekt und die dazugehörigen Channels

Das Element <application> beinhaltet Informationen über alle Remote Objekte die von der Applikation benutzt oder geposted werden

Das Element <service> beinhaltet die Elemente die von der Anwendung veröffentlicht werden sollen

Das Element <wellknown> Registrieren des Objektes welches vom Server veröffentlicht werden soll.

 

Zu beachten an dieser Stelle ist, dass es die Elemente <wellknown> für den Server und für den Client gibt. Eine genauere Beschreibung aller Elemente des Konfigurationsfiles finden Sie unter der MSDN .net Hilfeseite : help://MS.VSCC/MS.MSDNVS/cpgenref/html/gnconremotingsettingsschema.htm

Wichtig ist das Element <wellknown> mit seinen Attributen. Sie sehen bei mir das Attribut type ="" welches den NamespaceNamen + Klassennamen sowie den Namen des Assemblies beinhaltet. Ausserdem ist das Attribut mode="" wichtig, denn hier wird festgelegt wie das Objekt aktiviert werden kann. Zur Auswahl stehen hier Singleton oder SingleCall. Singleton bdeutet, das für alle Requests nur eine einzige Instanz des Objektes erzeugt wird. SingleCall bedeutet genau das Gegenteil, es wird also pro Clientrequest eine eigene Instanz des Objekt erzeugt. Es muss eines Option ausgewählt werden! Zuletzt muss noch das Attribut objetUri="" gesetzt werden. Dieses bestimmt den Endpunkt der URI. Wenn Sie das Objekt wie in unserem Fall über den IIS veröffentlichen, müssen Sie hier .soap oder .rem angeben, damit der Request an das .net IHttpHandler Interface weitergereicht wird.

 

Handelt es sich bei Ihrem Objekt um eine Server Activated Object (Referenz) können Sie die benötigten Client Informationen per SoapSuds.exe erzeugen:

 

 SoapSuds.exe -URL http://<Computer>:<Port>/<VirtDir>/<ObjectURI>?wsdl

Handelt es sich um eine Client Activated Object müssen Sie so vorgehen:

 SoapSuds.exe -URL http://<Computer>:<Port>/<VirtDir>/RemoteApplicationMetadata.rem?wsdl

 

Nun zum Client:

Als Client verwende ich diesmal wieder eine WinForm Anwendung. Was hierbei umbedingt von Nöten ist, ist sind die MetaInformationen über Ihr Remote Objekt. Ansonsten könnnen Sie keine Compilierung durchführen. Die Schritte danach sind wie gehabt:

1. Namespace einfügen

2. Objektvariable vom Typ des RemoteObjekts erzeugen

3. Neue Instanz mit Activator.GetObject() holen.

4. Methoden aufrufen.

 

 using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.Remoting;
using myRemoteService;

namespace SimpleRemotingClient
{
 /// <summary>
 /// Einfacher Client für das HTTP Remoting Objekt SimpleRemotingServerObject
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {

...

private void button1_Click(object sender, System.EventArgs e)
  {
   myRemoteObject myClientObject = (myRemoteObject)Activator.GetObject(typeof(myRemoteObject), "http://w2k_dotNET/SimpleRemotingServerObject/SimpleRemotingServerObject.soap");
   label1.Text = myClientObject.myRemoteMethod("Tobi");
  }
 }

Was ich Ihnen leider noch vorenthalten habe ist, dass sie natürlich wie beim Server auch für den Client Konfigurationsdateien benutzen können anstatt wie ich es getan habe, hardcoden. Diese Config Dateien haben normalerweise den Namen ClientName.exe.config. Der Aufbau entspricht im wesentlichen des des Serverkonfig Files. Sie müssen jedoch im Clientquellcode die Konfigurationsdatei natürlich auslesen:

 RemotingConfiguration.Configure("Client.exe.config");

 

Zum Abschluss lässt sich sagen, dass uns mit dem .net Remoting Framework das Programmieren solcher Remoting Anwendungen um einieges erleichtert wird. Ich hoffe ausserdem, dass Sie die zweite Variante des Remoting über den SOAP Formatter liebgewinnen, da diese für eine Umgebung wie sie oft bei grossen Firmen zu finden ist (verschiedenste Plattformen), recht praktisch ist, da wir RPC calls von verschiedenen End Systemen durchführen können und das ganz einfach per SOAP und XML.

 

 


Erfasst am: 27.12.2001 - Artikel-URL: http://www.devtrain.de/news.aspx?artnr=680
© Copyright 2003 ppedv AG - http://www.ppedv.de