Announcement

Collapse
No announcement yet.

Ein klein wenig Remoting ?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Ein klein wenig Remoting ?

    Ich remote gerade zum ersten mal und ein wenig klappt es, aber ich bin auf
    Problem gestossen das ich mir nicht erklären kann. Es hat wohl was mit den Channels zu tun.


    Ich habe eine normale Anwendung die ein Objekt als Singleton zur Verfügung stellt auf dem localhost. Eine Client holt sich nun einen Verweis auf dieses Objekt, genau genommen wohl eigentlich einen Proxy wovon man allerdings nix mitbekommt. Es klappt ja auch soweit..


    Mein RemoteObject:

    Code:
    [Serializable]
    class myCustomClass : MarshalByRefObject
    {
           public string name;
    
           public myCustomClass (){  name = "xx"; }
    }
    
    
    [Serializable]
    class myRemoteObject : MarshalByRefObject
    {
         public myCustomClass myClassObject = new myCustomClass ()
    
         public myRemoteObject(){}
         public void HelloMethod(string sMsg){MessageBox.Show(sMsg);}
    }

    Mein Server:

    Code:
    TcpChannel myChannel = new TcpChannel(3021);  ChannelServices.RegisterChannel(myChannel);
    RemotingConfiguration.RegisterWellKnownServiceType(typeof(myRemoteObject), "RemoteObject", WellKnownObjectMode.Singleton);
    myRemoteObject myObject = (myRemoteObject)Activator.GetObject(typeof(myRemoteObject),"tcp://localhost:" +  3021.ToString() + "/RemoteObject" );

    Mein Client:
    Code:
    TcpChannel myChannel = new TcpChannel(3021);
    ChannelServices.RegisterChannel(myChannel);
    myRemoteObject myObject =  (myRemoteObject)Activator.GetObject(typeof(IVWebServiceClient),"tcp://localhost:" +  3021.ToString()  +  "/RemoteObject");

    Was ist nun das Problem ?
    Wenn ich auf dem RemotingObject eine primitive Methode aufrufe klappt das.

    myRemoteObject.HelloMethod("Das ist ein Test");
    // Klappt ganz wunderbar


    Wenn ich versuche auf ein Member des RemoteObjects direkt zuzugreifen,
    geht die Sache ordentlich schief.


    string s = myRemoteObject.myClassObject.name;
    // Lustige Exception

    "Der Remoteproxy hat keinen Channelempfänger, d.h. der Server besitzt keine registrierten Serverchannel oder die Anwendung hat keinen passenden Clientchannel, um mit dem Server zu kommunizieren."


    Ich versuche ja hier auf eine eingebettete Instanz einer anderen von mir erstellten Klasse zuzugreifen. Braucht diese Klasse einen extra Channel oder wo liegt das Problem.


    Ich hoffe ich hab's nicht zu sehr aufgebläht, aber manchmal macht eine genau Beschreibung eben auch den Unterschied.


    Viele Grüsse
    Sebastian

  • #2
    Also nach diversen Experimenten ...


    MyCustomObject mco = MyRemotingObject.CustomObject;

    Die Klasse CustomObject darf sich nicht von MarshalByRefObject
    ableiten dann funktionierts. Blöderweise ist CustomObject bei mir von
    System.Web.Services.Protocols.SoapHttpClientProtoc ol abgeleitet und da steckt MarshalByRefObject mit drin. Der Ärger hört einfach nicht auf :/

    Weiss evtl. jemand eine Lösung ? Ich kann selbst im RemotingObject
    nicht auf CustomObject zugreifen, das ist extrem schlecht.
    Allerdings nur wenn ich von aussen aufrufe.

    class MyRemotingObject
    {

    CustomObject mco;

    // Konstruktor -wird aufgerufen wenn die
    // Serveranwendung das Object registriert bzw.
    // die erste Funktion aufgerufen wird.
    public MyRemotingObject()
    {
    mco = new CustomObject ();
    mco.SampleFunction("hey"); //funktioniert
    }

    // Funktion wird von der Clientanwendung aufgerufen
    public mySampleFunction()
    {
    mco.SampleFunction("hey"); // wirft die proxy-exception
    }

    }

    Comment


    • #3
      Hallo Sebastian.Lange,

      mal ein paar Vermutungen:
      wofür ist die Zeile
      Code:
      myRemoteObject myObject = (myRemoteObject)Activator.GetObject(typeof(myRemoteObject),"tcp://localhost:" +  3021.ToString() + "/RemoteObject" );
      im Servercode? Benötigst Du einen Zugriff auf entsprechendes Remoting Objekt, dann verwende den selben Code, den Du auch im Client verwenden würdest, um die Instanz davon zu holen.

      Warum folgende Inkosistenz:
      Code:
      (myRemoteObject)Activator.GetObject(typeof(IVWebServiceClient)...
      Du versuchst ein WebServiceClient Objekt auf myRemoteObject zu casten, ich weiß nicht was passiert, wenn man bei GetObject() den falschen Typ angibt. Verwende hier beides mal "myRemoteObject".

      Folgende Tipps:
      - Verwende nie von extern Direktzugriff auf Klassenvariablen, definiere Klassenvariablen immer als "private", verwende Properties (getter/setter) für den Zugriff.
      - Verwende Interfaces, die die Struktur der Klasse vorschreiben, das entkoppelt die Implementierung von der Klassenstruktur, gerade für Remoting ist das sehr entscheidend. Hier müsste dann jeweils nur das Interface dem Server und dem Client bekannt gemacht werden. Während der Server eine konkrete Implementierung verwendet braucht der Client keine Kenntniss davon haben. Sollten Implementierungsänderungen vorgenommen werden, so müssen diese nur auf dem Serverobjekt gemacht werden, der Client benötigt keine weitere Anpassung.

      Ich denke dann sollte das auch mit dem Remoting klappen.

      Grüße
      _ntr_

      Comment

      Working...
      X