Laden...

Remoting-Helfer

Letzter Beitrag vor 13 Jahren 60 Posts 66.613 Views
Remoting-Helfer

Ich habe neulich einen kleinen Remoting-Helfer gebaut. Ziel war es, den Aufwand der Veröffentlichung eines Objekts für den entfernten Zugriff über TCP/IP auf ein Minimum zu reduzieren.

Herausgekommen ist eine Klasse mit ein paar statischen Methoden, die sich als Tool-Assembly in beliebigen Projekten verwenden lässt.

Feature-Liste:*Unkompliziertes Remoting ohne Konfigurationsdateien oder unverständliche Kanal-Einstellungs-Hastables *Veröffentlichung eines existierenden Objekts mit nur einer Zeile C#-Code *Konsumieren eines entfernten Objekts auf der Clientseite mit nur eine Zeile C#-Code *Unterstützung für Authentifizierung und sichere Übertragung (Optional)

Anwendungsbeispiel:

Angenommen ich habe eine Klasse mit Namen ServerSideCalc geschrieben, die bestimmte Berechnungen ausführt. Diese soll in einer Server-Anwendung laufen und ihre Funktionalität beliebig vielen Client-Programmen über TCP-Netzwerkzugriff zugänglich machen. Der Server soll über den TCP-Port 9400 angesprochen werden und die übertragenen Daten automatisch verschlüsseln. All diese Anforderungen werden mit folgender Zeile C#-Code umgesetzt:


// ServerSideCalc-Objekt unter dem Namen "Uschi" auf TCP-Port 9400 veröffentlichen
RemotingHelper.PublishObjectOverTCP(calc, "Uschi", 9400, true, true);

Auf der Client Seite kann das Objekt verwendet werden, als wäre es ein herkömmliches lokales Objekt. Dazu muss lediglich eine Verbindung zum entfernten Objekt aufgebaut werden. Das geht so:


// Verbindung zu entferntem Objekt mit dem Namen "Uschi" über TCP auf Server 192.168.0.100 herstellen
ServerSideCalc calc = (ServerSideCalc)RemotingHelper.GetRemoteObjectOverTCP(typeof(ServerSideCalc), "Uschi", "192.168.0.100", 9400, true, true);

Im Anhang befindet sich noch eine ZIP-Datei meiner einer kompletten Visual Studio 2005 Projektmappe. Enthalten sind:*Die eigentliche Tool-Bibliothek Rainbird.Tools.EasyRemoting *Ein Test-Host: Rainbird.Tools.EasyRemoting.TestServer *Eine Assembly mit Test-Geschäftslogik: Rainbird.Tools.EasyRemoting.TestObjects *Eine Windows.Forms Test-Oberfläche: Rainbird.Tools.EasyRemoting.TestClient

Hoffentlich gefällt Euch das kleine Tool.

Edit: Nun ist auch das Beispiel-Objekt mit unbegrenzter Lebensdauer ausgestattet.

Edit: Es gibt bereits eine neuere Version (1.1.0.0) unter: Remoting-Helfer

Version 1.0.0.0 (veraltet)

Hallo,
sieht interesant aus, werds mal testen

DANKE!

hab das Tool beim Versuch mich in Remoting einzuarbeiten entdeckt und bin begeistert! Hat mir erstmal einiges an Zeit erspart...

Hi,

wenn ich allerdings die beiden Anwendungen starte und der Server ca. 15-20 min keine Anfrage erhält wird danach beim Remoteaufruf eine RemotingException (Das Objekt /Uschi wurde getrennt oder ist nicht auf dem Server vorhanden) ausgelöst.

Ideen?

Also das Problem tritt bei Rainbirds und bei meiner Anwendung auf. Wenn der Server etwas länger nicht angesprochen wird kann der Client das Objekt nicht mehr referenzieren. Soweit ich recherchiert habe hängt das schätzungsweise wohl mit der Garbage Collection (Lifetime) zusammen, hab aber noch keine Lösung gefunden..

Hallo decay,

dann wird wohl GC.KeepAlive helfen.

herbivore

Hallo,

danke, aber hat es leider nicht getan, dann war meine Annahme wohl falsch...

Decay

Da ich noch keine Lösung für das Problem gefunden habe:

Hat jemand von euch die Komponente schon mal getestet und kann das Verhalten bestätigen / nicht bestätigen?

Decay

Dies ist das std verhalten von Remoting.

Schon mal bei Remoting was von Lease gelesen?

hallo decay,

du musst bei dem Objekt, welches du per Remoting (von MarshalByRefObject) nutzt, die Methode InitializeLifetimeService überschreiben


public override object InitializeLifetimeService () {
    return null;
}

Return null hat den Effekt, dass das Objekt während der gesamten Lebenszeit des Servers aktiv (am leben) bleibt.

Sorry, Mein Fehler

Oh, darauf hab ich bei meinen kleinen Tests gar nicht geachtet.

Wird sofort nachgebessert.

Danke für den Hinweis! 8.281 Augenpaare sehen eben mehr als nur eins.

Original von FZelle
Dies ist das std verhalten von Remoting.

Schon mal bei Remoting was von Lease gelesen?

Jaaah, das es was damit zu tun haben könnte hab ich ja oben schon erwähnt, hatte leider recht wenig Zeit und konnte mich nicht in das Thema einarbeiten. Hab gedacht jemand hat eine schnelle Lösung für mich..

@Parsifal: Tausend Dank!!

Hallo Rainbird,

Zuerst einmal : Vielen Dank. Topartikel & hervoragend dokumentierten Code. Ich habe mir das Miniprojekt einmal angeschaut. Und ich muss sagen, ich bekam ein guter Einblick in das Remoting von .NET für den Anfang.

Da ich nun so als "Testprojekt" etwas in diese Richtung realisieren möchte, wollte ich nach der Lizenzierung fragen..?! Ich meine nur, dass du nicht "dumm" schaust, wenn du Code Snippets von deinem Projekt irgend in einem Projekt auf Codeplex.com findest 😉...

Vielen Dank nochmals.

Grüsse, pro

Hallo Rainbird,

ich habe mich schon eine ganze Weile versucht mit Remoting zu beschäftigen. Allerdings haben mich die vielen Infos, Seiten und Bemerkungen eher verwirrt.

Ich war schon etwas "deprimiert" bis ich Dein Projekt entdeckt habe. Das ist einfach gehalten, prima erklärt und hat mir geholfen, Remoting endlich etwas zu verstehen.

Zumindest fühle ich mich in der Lage, jetzt was Eigenes zu machen.

Vielen Dank

Thomas

Lizenzierung

Original von pro
Da ich nun so als "Testprojekt" etwas in diese Richtung realisieren möchte, wollte ich nach der Lizenzierung fragen..?! Ich meine nur, dass du nicht "dumm" schaust, wenn du Code Snippets von deinem Projekt irgend in einem Projekt auf Codeplex.com findest 😉...

Ich habe da nichts dagegen. Meine Snippets darfst Du gerne in eigene Projekte einbauen. Das dürfen auch kommerzielle Projekte sein.

Allerdings möchte ich nicht, dass jemand meine Snippets direkt als Tool-Komponenten etc. unter seinem Namen verkauft.

Hallo Rainbird,

ich wollte deine Komponente in meinem Projekt verwenden, bin aber dabei auf ein Problem gestoßen das wie folgt aussieht:

Ich habe eine Server und eine Client Klasse. beim anmelden, registriert sich der Client beim Server und übergibt sein Client-Objekt. Der Server könnte nun theoretisch dem Client selbstständig Nachrichten übermitteln was ja dann mit einem "Observer" vergleichbar wäre. Leider taucht bei dem Versuch vom Server auf den Client zuzugreifen immer folgende Exception auf:

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 habe noch von meiner ersten Remoting-Andendung folgenden Code für den Remotingaufbau, der hier aber funktioniert:

für den Server:


BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

IDictionary props = new Hashtable();
props["port"] = 9991;
props["typeFilterLevel"] = TypeFilterLevel.Full;

TcpChannel channel = new TcpChannel(props, null, serverProvider);
ChannelServices.RegisterChannel(channel, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestServerClass), "test", WellKnownObjectMode.Singleton);

und für den Client:


BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

IDictionary props = new Hashtable();
props["port"] = 0;
props["name"] = channelName;
props["typeFilterLevel"] = TypeFilterLevel.Full;

String url = "tcp://" + "127.0.0.1" + ":9991/test";

TcpChannel channel = new TcpChannel(props, clientProvider, null);

ChannelServices.RegisterChannel(channel, false);

IServer tmp = (IServer)Activator.GetObject(typeof(IServer), url);

Lg XXX

//EDIT: bin draufgekommen warums bei mir geht und bei deiner Komponente nicht.
In der folgender Methode fehlt die angegebene Zeile:


public static void SetupClientChannel(bool enableSecurity, bool impersonate)
{
    .
    .
    //ausgeblendeter Code
    .
    .

    // diese Zeile bewirkt komischerweise, dass der Server auf die Clients zugreifen kann. Leider kann ich nicht erklären warum dies der Fall ist :)
    channelSettings["port"] = 0;

    .
    .
    //ausgeblendeter Code
    .
    . 
  }
}

Also wenn du nichts dagegen hast, würd ich gerne diese Funktionalität in der Komponente verwenden.

Lg XXX

Seltsam

Ich kann mir das auch nicht erklären. Seltsam!

Wenn ich Zeit habe, werde ich mir das näher ansehen und es vielleicht auch selber in meine Komponente einbauen, wenn es zuverlässig läuft. Bisher habe mit EasyRemoting noch nicht in Client-als-Server-Szenarien eingesetzt. Deshalb ist mir der Fehler wohl auch noch nicht untergekommen.

Ich habe nichts dagegen, wenn Du die Komponente an Deine Bedürfnisse anpasst oder sie umbaust.

Hallo Rainbird,
also wirklich ... ein Top Einstieg in Remoting.
Ich habe leider ein Problem.

Laufen Client und Server auf dem gleichen PC, ist alles easy.
Da das allerdings nicht der Sinn der Sache ist, läuft mein Server remote (VMware Virtual Machine mit Ethernet Adapter, IP Adresse bekannt).
In diesem Fall erhalte ich die Meldung:

"Eine Sicherheitsanforderung der Remoteseite wurde während der Authentifizierung nicht erfüllt. Erhöhen Sie ProtectionLevel und/oder ImpersonationLevel."

Was mache ich falsch?

Danke,
Christel

Es ist schlimm, eine Ausnahme zu sein, aber noch schlimmer, keine zu sein.

Kerberos

Hast Du den Parameter für die Sicherheit bei Client und Server gleich gesetzt?

Ansonsten:

Wenn der Remoting-Host auf einem Domänencomputer läuft, verwendet Remoting standardmäßig Kerberos als Authentifizierungsprotokoll. Kerberos ist super, da es besonders sicher ist. Allerdings verlangt Kerberos, dass der Server die Identität des Client prüfen kann und umgekehrt. Um die Identität der jeweiligen Gegenseite zu prüfen, fragt Kerberos beim Verzeichnisdienst (Active Directory) nach, ob es in der Domäne ein gültiges Computerkonto für den Computer der gegenseite gibt.

Sind nun nicht beide Computer in der selben Domäne (oder wenn einer der Computer gar nicht in einer Domäne ist), kann Kerberos kein Computerkonto für den anderen Computer finden. Die Authentifizierung wird dann sofort abgebrochen.

Die Remoting-Sicherheit funktioniert außerdem gar nicht unter Windows 98, Windows 98 SE und Windows Me!

Es gibt zwei Lösungen dafür:*Entweder Du joinst alle betroffenen Computer in die selbe Domäne bzw. definierst Vertrauensstellungen *oder Du verwendest NTLM statt Kerberos (NTLM prüft nicht die Identität des anderen Computers)

Wenn Du auf NTLM umstellen willst, musst Du das als Channel-Property übergeben.

Hallo und vielen Dank,

ich habe jetzt erstmal die Sicherheit bei Server und Client ausgeschaltet und jetzt funzt das ganze. Das reicht momentan für meine Bedürfnisse. Ich muss ertmal sehen, wie sich das ganze Projekt entwickelt (bin erst neu in der Firma) und dann bei Bedarf Deine Hinweise einarbeiten. Denke, dass ich das damit hinkriege.

Ich arbeite übrigens auf beiden Systemen unter Windows XP.
Einer der Computer ist nicht in einer Domäne.

Und nochmal ... Super Tool und Spitzen Programmierstil, habe mich damit in wenigen Stunden in Remoting einarbeiten können.

Gruß,
Christel

Es ist schlimm, eine Ausnahme zu sein, aber noch schlimmer, keine zu sein.

Danke

Danke für das positive Feedback.

Ich freue mich wenn meine Tools oder Snippets anderen hilfreich sind.

Rainbird,

Ich bin sehr interessiert in deine Lösung. Funktioniert es auch mit Pocket PC?

Paul.

Remoting & Pocket PC

Leider Unterstützt das Compact Framework kein Remoting.

Webdienst Prefomance Optimierung

Da wirst Du wohl auf Webservices zurückgreifen müssen.

Es wurden zwei verschiedene Objekte gefunden, die dem gleichen URI zugeordnet sind

Hi,

(tschuldigung, dass ich es quasi nochmal poste, aber mit deinem Tool tritt das gleiche Problem auf...

Also sowas funktioniert:

ServerSideCalc remoteObject = new ServerSideCalc();
RemotingHelper.PublishObjectOverTCP(remoteObject,"Uschi",123,true,true);
RemotingHelper.PublishObjectOverTCP(remoteObject,"Uschi",456,true,true);

Ich hätte gern aber sowas:

ServerSideCalc remoteObjectOne = new ServerSideCalc();
RemotingHelper.PublishObjectOverTCP(remoteObjectOne,"Uschi",123,true,true);

ServerSideCalc remoteObjectOneTwo = new ServerSideCalc();
RemotingHelper.PublishObjectOverTCP(remoteObjectTwo,"Uschi",456,true,true);

Da kommt aber immer die Exception "Es wurden zwei verschiedene Objekte gefunden, die dem gleichen URI zugeordnet sind, 373dda6a_d33a_4eff_b94d_27cf486bcefc/Uschi."

An sich würde ich das akzeptieren. Aber in dem Fall, dass ich den einen PublishObjectOverTCP-Aufruf in einer Anwendung und den anderen in einer anderen Anwendung ausführe, bekomme ich keine Exception... 🤔

Gruß
dN!3L

Also ich weiß jetzt zumindest, woran es liegt...

Beim Marshal() bekommt das zu veröffentlichende Objekt eine ID verpasst (kann man dann über RemotingServices.GetObjectUri() abfragen). Das ist zwar ein URI, ist aber nicht der URI, mit dem man das veröffentlichte Objekt dann erreichen kann. Besteht aber trotzdem aus dem PublicName, verbunden mit der ApplikationsID. Das führt dann auch dazu, dass es mit mehren Programminstanzen klappt.

Bekomm ich das noch irgendwie in eine einzige Applikation, oder muss ich das Veröffentlichen jeweils in eine zusätzliche Applikation verfrachten?

Gruß
dN!3L

P.S.: Das ist übrigens der StackTrace:

Fehler: System.Runtime.Remoting.RemotingException
bei System.Runtime.Remoting.IdentityHolder.SetIdentity(Identity idObj, String URI, DuplicateIdentityOption duplicateOption)
bei System.Runtime.Remoting.IdentityHolder.FindOrCreateServerIdentity(MarshalByRefObject obj, String objURI, Int32 flags)
bei System.Runtime.Remoting.RemotingServices.GetOrCreateIdentity(MarshalByRefObject Obj, String ObjURI)
bei System.Runtime.Remoting.RemotingServices.MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType, Boolean updateChannelData)
bei System.Runtime.Remoting.RemotingServices.MarshalInternal(MarshalByRefObject Obj, String ObjURI, Type RequestedType)
bei System.Runtime.Remoting.RemotingServices.Marshal(MarshalByRefObject Obj, String URI)

warum versuchst du 2 verschiedene objekte über ein und die selbe uri zu veröffentlichen?

das ist genauso als würdest du versuchen noch eine domain namens www.mycsharp.de übers internet erreichbar zu machen...

wie wäre es denn damit:

ServerSideCalc remoteObjectOne = new ServerSideCalc();
RemotingHelper.PublishObjectOverTCP(remoteObjectOne,"Uschi1",123,true,true);

ServerSideCalc remoteObjectOneTwo = new ServerSideCalc();
RemotingHelper.PublishObjectOverTCP(remoteObjectTwo,"Uschi2",456,true,true); 

Original von JAck30lena
warum versuchst du 2 verschiedene objekte über ein und die selbe uri zu veröffentlichen?

Versuche ich nicht. Der angemeckerte doppelte URI ist von Intern. Ich möchte zwei Objekte unter verschiedenen URIs veröffentlichen:
tcp://localhost:123/Uschi
tcp://localhost:456/Uschi

Wie man sieht, sind die(se) URIs nicht doppelt. Mit 2 Applikationen geht das ja auch, aber in einer meckert er rum, dass er dann 2x Uschi hätte (weil der Rest des VeröffentlichungsURI nicht beachtet wird).

das ist genauso als würdest du versuchen noch eine domain namens
>
übers internet erreichbar zu machen...

Nö, das ist so, als ob es www.mycsharp.de/news schon gibt, und ich www.tempuri.org/news registrieren möchte (was ja geht).

Gruß
dN!3L

der port entscheidet nicht über die position des .rem objektes.

edit: ist ungefähr so als ob du versuchen würdest in einem ordner 2 dateien zu haben die exakt gleich benannt sind.

Original von JAck30lena
der port entscheidet nicht über die position des .rem objektes.

Was für Positon?
Und warum geht es denn dann, wenn ich 2 Applikationen habe?

weil die app-id noch eine rolle spielt

wenn du ein und das selbe objekt durch 2 ports erreichbar machen möchtest dann musst du die entsprechenden channel beim server registrieren.

wenn du für jeden client ein eigenes objekt erreichbar machen willst musst du clientactivated objects nehmen.

ansonsten fallen mir keine gründe ein warum du das so machen möchtest.

Original von JAck30lena
wenn du ein und das selbe objekt durch 2 ports erreichbar machen möchtest dann musst du die entsprechenden channel beim server registrieren.

Siehe oben. Das geht ja.

Ich möchte ja 2 **verschiedene **Objekte unter 2 verschiedenen Ports veröffentlichen. Und nochmal: Das GEHT, allerdings nur, wenn ich diese beiden Objekte auch in verschiedenen Anwendungen/-sinstanzen veröffentliche, aber nicht in ein und der selben Anwendung.

Gruß
dN!3L

Hallo @Rainbird!

Is echt der Hammer das Tool, funktoniert auch super.

Ich würde gerne statt mit der IP lieber mit http:/www.MeinRechner.de da ich eine IP weiterleitung habe zugreifen.

Das soll keinesfals Kretik sein, ganz im Gegenteil bin hell auf begeistert von deinem Tool!

Hoffe ich mach hier keine Umstände!

Gruß, Joachim

Gruss, GIJOE

Auch Anfänger haben recht auf Leben! 😁

Ok!

Wer lesen kann ist klar im Vorteil.

Es steht ja vor dem www. eh schon TCP://, damit kann man das http:// weglasen.

Geiles teil!

Gruß, Joachim

Gruss, GIJOE

Auch Anfänger haben recht auf Leben! 😁

Erweiterung der Remoting-Helfers für Veröffentlichung von Typen

Alle die nicht manuell einzelne bereits existierende Objekte veröffentlichen wollen, sondern Typen, deren Objekte bei Bedarf (SingleCall) oder als Singleton automatisch erzeugt werden, sollten folgenden Code in die RemotingHelper-Klasse einfügen:

     
        /// <summary>
        /// Veröffentlicht einen beliebigen von MarshalByRef abgeleiteten Typ als Singleton über einen 
        /// TCP-Kanal für entfernten Zugriff.
        ///
        /// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation 
        /// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt. 
        /// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
        /// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
        /// </summary>
        /// <remarks>
        /// Der TCP-Kanal wird automatisch konfiguriert und registriert. Die Kanal-Registrierung bleibt 
        /// über diesen Prozeduraufruf hinaus gültig. Wenn sie die selbe TCP-Anschlussnummer mehrmals an
        /// diese Methode übergeben, wird der bestehene Kanal verwendet. Die Sicherheitskonfiguration des 
        /// ersten Aufrufs ist deshalb entscheidend. Wenn sie für spätere Aufrufe andere Werte für die
        /// Parameter "enableSecurity" oder "impersonate" angeben, werden diese nicht berücksichtigt, 
        /// da der bestehende Kanal verwendet wird!
        /// </remarks>
        /// <param name="type">Zu veröffentlichender Typ</param>
        /// <param name="publicName">Öffentlicher Name (Über diesen Namen greifen Clients entfernt auf das Objekt zu!)</param>
        /// <param name="tcpPort">TCP-Anschlussnummer</param>
        /// <param name="enableSecurity">Schalter für Sicherheit</param>
        /// <param name="impersonate">Schalter für Impersonierung</param>
        public static void PublishSingletonTypeOverTCP(Type type, string publicName, int tcpPort, bool enableSecurity, bool impersonate)
        {
            // Kanal einrichten (Falls dies noch nicht geschehen ist!)
            SetupServerChannel(tcpPort, enableSecurity, impersonate);

            // Typ Singleton-Aktiviert veröffentlichen
            RemotingConfiguration.RegisterWellKnownServiceType(type, publicName, WellKnownObjectMode.Singleton);
        }

        /// <summary>
        /// Veröffentlicht einen beliebigen von MarshalByRef abgeleiteten Typ als SingleCall über einen 
        /// TCP-Kanal für entfernten Zugriff.
        ///
        /// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation 
        /// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt. 
        /// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
        /// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
        /// </summary>
        /// <remarks>
        /// Der TCP-Kanal wird automatisch konfiguriert und registriert. Die Kanal-Registrierung bleibt 
        /// über diesen Prozeduraufruf hinaus gültig. Wenn sie die selbe TCP-Anschlussnummer mehrmals an
        /// diese Methode übergeben, wird der bestehene Kanal verwendet. Die Sicherheitskonfiguration des 
        /// ersten Aufrufs ist deshalb entscheidend. Wenn sie für spätere Aufrufe andere Werte für die
        /// Parameter "enableSecurity" oder "impersonate" angeben, werden diese nicht berücksichtigt, 
        /// da der bestehende Kanal verwendet wird!
        /// </remarks>
        /// <param name="type">Zu veröffentlichender Typ</param>
        /// <param name="publicName">Öffentlicher Name (Über diesen Namen greifen Clients entfernt auf das Objekt zu!)</param>
        /// <param name="tcpPort">TCP-Anschlussnummer</param>
        /// <param name="enableSecurity">Schalter für Sicherheit</param>
        /// <param name="impersonate">Schalter für Impersonierung</param>
        public static void PublishSingleCallTypeOverTCP(Type type, string publicName, int tcpPort, bool enableSecurity, bool impersonate)
        {
            // Kanal einrichten (Falls dies noch nicht geschehen ist!)
            SetupServerChannel(tcpPort, enableSecurity, impersonate);

            // Typ SingleCall-Aktiviert veröffentlichen
            RemotingConfiguration.RegisterWellKnownServiceType(type, publicName, WellKnownObjectMode.SingleCall);
        }

Die beiden Funktionen sind eigentlich selbsterklärend. Eine für Singleton und eine für SingleCall.

@dN!3L: Vielleicht ist die Aktivierung des Typs per SingleCall für Dich eine Alternative? Dabei würde Dein Remoting-Server automatisch für jede Clientanfrage ein Objekt des typs erzeugen und danach wieder entsorgen. Wenn man die Objekte statuslos hält, ist dies die skalierbarste Methode, um Remoting zu verwenden.

Schön dass Euch mein kleines Tool so gut gefällt.

Original von Rainbird
@dN!3L: Vielleicht ist die Aktivierung des Typs per SingleCall für Dich eine Alternative? Dabei würde Dein Remoting-Server automatisch für jede Clientanfrage ein Objekt des typs erzeugen und danach wieder entsorgen. Wenn man die Objekte statuslos hält, ist dies die skalierbarste Methode, um Remoting zu verwenden.

Das "Problem" ist, dass diese Objekte einen Zustand haben. Durch die Verwendung von RegisterWellKnownServiceType kam dann noch hinzu, dass ich die veröffentlichten Objekte nicht mehr deregistrieren kann.
Gelöst hab ich es durch eine Factory, die ich marshallen und disconnecten kann. So kann ich in meiner Serveranwendungen mehrere Objekte unter dem gleichen Namen (aber nicht gleichzeitig) anbieten und hab es halt hingenommen, das in ein und der selben Anwendung nicht gleichzeitig 2 Objekte mit dem gleichen Namen exisitieren können (ist halt ein kleiner Schönheitsfehler 😦).

Ich hab zwar immer noch das Gefühl, dass mein Problem nicht wirklich verstanden wurde, aber ich will da jetzt nicht weiter drauf rumreiten. Weitere Diskussionen dazu bitte in Remoting: Gleichen Namen für unterschiedliche Objekte/Port benutzen =)

Gruß
dN!3L

Hollo @Rainbird

Kann man auch in deinem Tool als Kommunikationsmittel einen NetworkStream einsetzen?

Ich frage das deshalb, weil ich gerne Daten versenden möchte und beim jeweiligen Client per Event einen Downloadstatus realisieren möchte.

Im momentanen Zustand versendet er die Daten und empängt die Daten auf einen Schwung.

Die Anfrage sieht im Moment bei mir so aus:

//Client
buffer = calc.GetFile(pfad)


//Server
public Byte[] GetFile(string pfad)
{
                FileStream fs = new FileStream(pfad, FileMode.Open, FileAccess.Read);
                Byte[] buffer = new Byte[fs.Length];
                long bytesreader = fs.Read(buffer, 0, fs.Length);
                return(buffer);
}

Wäre schön wenn es da ne möglichkeit giebt, komm leider selber nicht drauf!

Gruß, Joachim

PS: Vielen Dank im Voraus!

Gruss, GIJOE

Auch Anfänger haben recht auf Leben! 😁

Remoting und Streams

Hallo GIJOE,

Remoting ist ein Werkzeug, um entfernte Methodenaufrufe durchzuführen. Die Rückgabewerte einer aufgerufenen Funktion werden vom Host zum Client an einem Stück übertragen. Übertragen werden können alle serialisierbaren Typen. NetworkStream ist von MarshalByRef abgeleitet und nicht serialisierbar. Du müsstest die Daten eben als byte[] übertragen. Die Übertragen wäre in jedem Fall an einem Stück. Eine Fortschrittsmessung ist soweit ich weiss nicht möglich.

Remoting sollte man nicht verwenden, um große Dateien übers Netzwerk zu senden. Dafür wurde es nicht entworfen. Du solltest vielleicht einen anderen Weg wählen. Mit System.Net.Security.NegotiateStream kannst Du Datenströme sicher übers Netzwerk schicken. Oder Du könntest WCF verwenden (das hat Streaming-Unterstützung).

Hallo @Rainbird!

Habe verstanden was du mir erklärt hast!

Es ist halt so, dein Tool funktioniert einwndfrei und ich als Server muß nicht wissen was der andere für ein Port zu verfügung stellt um durch seine Firewall durch zu kommen. Mit meinem TCPListener ServerClient Prog versuch bin ich leider genau an dieser Stelle gescheitert, da muß ich den Clienten auffordern einen Port frei zu geben um das ich daten mit ihm austauschen kann. Und wie du sicherlich selbst weist, ist das sehr umständlich. Aber ich werde mir deinen Rat zu Herzennehmen und es mit System.Net.Security.NegotiateStream oder WCF versuchen, vieleicht finde ich ja da nen Weg ohne die ständige Port angabe Daten auszutauschen.

Dein Remoting Prog. bekommt bei mir allerdings trotzdem einen Ehrenplatz auf meiner Festplatte, ist sehr vielseitig einsetzbar und funktioniert halt einfach!

Gruß, Joachim

Gruss, GIJOE

Auch Anfänger haben recht auf Leben! 😁

Version 1.1.0.0

Ich habe eine neue Version von EasyRemoting erstellt. Diese trägt die Versionsnummer 1.1.0.0 und enthält fogende Neuerungen/Bugfixes:*Bug beim serverseitigen Aufruf von Client-Objekten behoben (Port=0) *Veröffentlichung vpn Typen statt konkreter Objekte wird nun unterstützt (SingleCall & Singleton)

Ich habe eine neue Version von EasyRemoting erstellt

Trifft sich gut - kann ich nämlich grad gut gebrauchen 🙂 Danke!

hallo Rainbird, ich habe mir gerade deinen RemotinHelper angeschaut und bin wirklich beeindruckt.
wirklich schön.
Nun habe ich mal eine Frage.

ich habe einen pc mit 2 netzwerkkarten als RemotingServer
und einen clientpc der über die 2. Netzwerkverbindung vom Server mit dem Server kommunizieren soll.
Nun ist es so, dass dein Beispiel nur funktioniert wenn ich die erste Netzwerkverbindung
deaktiviere...
Ist sie aktiv so meldet der Client das die Verbindung abgelehnt wurde...
Ist dies nun ein Fehler oder entspricht, dieses Verhalten einfach der Natur?

Vielen Dank soweit... soma

Remoting auf Multi-Homed-Server

Hallo soma,

das Problem ist bekannt. Es liegt aber nicht an meinem Remoting-Helfer, sondern an der .NET Implementierung des TcpChannels. Dieser arbeitet intern über einen Socket. Der Socket ist an eine Netzwerkkarte gebunden. Eine Anfrage von einer anderen Netzwerkkarte kommt deshalb gar nicht an.

Ein ähnliches Problem wird hier beschrieben: http://codicesoftware.blogspot.com/2008/10/troubles-in-net-remoting-when-ip.html

Leider kann ich Dir da momentan keine Lösung anbieten.

hallo,

irgendwie klingt das alles hier sehr beeindruckend, leider verstehe ich den sinn nicht so ganz und was man damit für vorteile hat und überhaupt allgemein machen kann.

ich habe zum beispiel eine anwendung die auf 5 verschiedenen rechnern läuft. wichtig wäre ein usercontrol auf der form das immer das gleiche anzeigen soll. dazu muss das control mit den anderen entfernten instanzen kommunizieren. wäre sowas hiermit möglich? auch zum beispiel genaue scrollbarpositionen etc zu streamen?

bitte klärt mich mal schnell auf 😃 finde das sehr interessant und das löst vielleicht meine vielen probleme zurzeit. danke schonmal!

prinzipiell kannst du das hiermit auch lösen.

okay, aber wie wäre sowas grundsätzlich möglich? um was handelt es sich hier genau bei dieser remoting class?

du solltest dich erstmal ein wenig grundlegend mit RPC und remoting beschäftigen.

das snippetforum ist für so eine diskussion denkbar ungeeignet.

Hallo Rainbird,

ich kam jetzt endlich auch mal in den Genuss deine Komponente zu benutzen und muss sagen das Ding ist echt cool!
Also Vielen Dank dafür.

Danke für die Blumen

Hallo jaensen,

schön dass Dir der Remoting-Helfer von Nutzen ist. Für die kleinen knusprigen RPC-Features morgens halb zehn in Deutschland ist die Komponente genau richtig.

Mach mal die Jalousien hoch 😉

[EDIT]
Oder eine Uhr mit Digitalanzeige...

Remoting ist garnicht so schwer, wie es auf den ersten Blick erscheinen mag.

Grüße Stephan

Servus Rainbird,
dein RemotingHelper gefällt mir nach wie vor sehr gut und verrichtet auch anstandslos seinen Dienst. Eine kleine Sache bekomme ich aber nicht gebacken:
Wie kann man den Timeout auf dem TcpChannel setzen?