Laden...

Net.Remoting Verbindungsstatus herausfinden

Erstellt von Stipo vor 13 Jahren Letzter Beitrag vor 13 Jahren 4.104 Views
Stipo Themenstarter:in
699 Beiträge seit 2007
vor 13 Jahren
Net.Remoting Verbindungsstatus herausfinden

Hallo zusammen,

ich suche derzeit, wie ich in Net.Remoting den Verbindungsstatus heraus bekommen kann.

ich verbinde mich mit folgender Methode zu dem Server. Nur liefert die Methode immer die Instanz zurück, selbst wenn keine Verbindung zum Server besteht.

public object Connect(string remoteName, Type remoteObjectType, IPEndPoint remoteEndPoint)
        {
            /* check arguments */
            if (remoteName == null) throw new ArgumentNullException("remoteName");
            if (remoteObjectType == null) throw new ArgumentNullException("remoteObjectType");
            if (remoteEndPoint == null) throw new ArgumentNullException("remoteEndPoint");

            /* check contraints */
            if (remoteEndPoint.AddressFamily != AddressFamily.InterNetwork) throw new ArgumentException("The address family of remoteEndPoint must be of type internetwork (ipv4)");

            string hostUrl = "tcp://" + remoteEndPoint.ToString() + "/" + remoteName;

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

            BinaryClientFormatterSinkProvider clientSinkProvider = new BinaryClientFormatterSinkProvider();

            Hashtable channelProperties = new Hashtable();
            channelProperties["name"] = remoteName + ":" + Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture);
            channelProperties["port"] = 0;

            TcpChannel channel = new TcpChannel(channelProperties, clientSinkProvider, serverSinkProvider);

            /* boot instance */
            object instance = Activator.GetObject(remoteObjectType, hostUrl);
            
            ChannelServices.RegisterChannel(channel, false);
            
            /* everything ok, add channel */
            lock (_channels)
            {
                if (!_channels.ContainsKey(remoteName))
                {
                    _channels.Add(remoteName, channel);
                }
            }
            return instance;
        }

Okay, wenn man dann die Methoden der Instanz aufruft, bekommt man eine Exception, die man dann fangen und behandeln kann.
Aber gibt es keine möglichkeit, den Verbindungsstatus schon in der Connect()-Methode zu prüfen, das die Methode ggf ein NULL oder eine Exception zurück geben kann?

Grüße Stephan

3.728 Beiträge seit 2005
vor 13 Jahren
Remoting überwachen

Hallo Stipo,

da gibt es Möglichkeiten.

  1. Über einen TrackingHandler: MSDN: .NET Remoting Überwachungsdienst
  2. Über ein eigene clientseitige Kanalsenke, die den Verbindungsstatus protokolliert und z.B. über Events der Client-Anwendung mitteilt.

Warum ist der Verbindungsstatus so wichtig für Dich?

Remoting kümmert sich automatisch darum.
Wenn Dir das Caching der Sockets auf den Keks geht (zwecks NLB etc.) kannst Du das per Channel-Property abschalten und den Timeout auf 0 setzen. Dann macht Remoting für jeden Aufruf einen eigenen Socket auf.

Stipo Themenstarter:in
699 Beiträge seit 2007
vor 13 Jahren

Hallo Rainbird,

Warum ist der Verbindungsstatus so wichtig für Dich?

Sinn ist, wenn sich ein Client über obige Methode mit dem Server vebindet, herauszufinden, ob eine verbindung zustandegekommen ist und dann eine Variable gesetzt wird, diese man dann mit IsConnected abfragen kann.

Werde mir die beiden möglichkeiten von dir mal ansehen.

Grüße Stephan

3.728 Beiträge seit 2005
vor 13 Jahren
IsConnected

Hallo Stipo,

Dir ist aber schon klar, dass die Socket-Verbindung erst hergestellt wird, wenn ein Methodenaufruf über den Proxy stattfindet und dass der Socket anschließend wieder freigegeben wird (ggf. verbleibt der Socket noch einige Zeit in einem Pool/Cache)?

Es nicht so, dass Remoting eine Verbindung zum Server öffnet, wenn der Proxy erzeugt wird und diese über die gesamte Lebensdauer des Proxies aufrechterhält.

Das macht eine IsConnected-Abfrage etwas schwierig. Die Verbindung besteht ja nur für einen ganz kurzen Moment (und das ist auch gut so, da ansonsten Dinge wie Network Load Balancing nicht möglich wären). Auch wenn der Socket nach dem Aufruf noch eine Zeit lang in einem Cache vorgehalten wird, ist er trotzdem nicht mehr mit einem konkreten Objekt verknüpft.

Die Frage ist, ob IsConnected den tatsächlichen Zustand der Socketverbindung zum Server zurückgeben soll/muss? Wenn dem so ist, wäre die Property zu 99.9% der Lebenszeit des Proxies auf False gesetzt.

Die nächste Frage ist, wo Du die IsConnected-Variable einbauen willst?

Generell hast Du bei Remoting keine direkte Kontrolle über die Socketverbindung, da diese von der TransportSenke (transport sink) des verwendeten Remoting-Kanals gekapselt ist.
Wenn Du - warum auch immer - volle Kontrolle über die Socketverbindung haben willst, müsstest Du einen eigenen Remoting-Kanal implementieren (ähnlich wie die vorgefertigten TcpChannel, HttpChannel und IpcChannel). Das ist allerdings ein etwas größerer Aufwand, da der Channel selbst und auch seine Transportsenken implementiert werden müssen. Für gewöhnlich werden eigene Kanäle nur dann geschrieben, wenn man ein Protokoll (z.B. UDP, SMTP oder ein eigenes properitäres Protokoll) zusammen mit Remoting verwenden will, dass standardmäßig unterstützt wird.

Hier ein Beispiel für die Implementierung eines UDP-Kanals: UDP Custom Channel C# .NET Remoting Program Example
Achtung! Der Link enthält mehere Kapitel! Ganz unten auf der Seite kann man weiterblättern (sieht man nicht unbedingt auf den ersten Blick).

Geht es Dir bei der IsConnected-Geschichte um Fehlerbehandlung?

Stipo Themenstarter:in
699 Beiträge seit 2007
vor 13 Jahren

Hallo Rainbird,

Das ist mal eine klare ansage, das es so nicht gehen wird. Okay, dann muss ich mich wohl von meinem Gedanken verabschieden.

Geht es Dir bei der IsConnected-Geschichte um Fehlerbehandlung?

Konkret ging es mir darum, das ich Clientseitig mich ja mit dem Server verbinde.
Nachdem ich mich dann verbunden habe, hängt sich der Client an diverse Events ran, was aber ja nicht geht, wenn der Client nicht mit dem Server verbunden ist (SocketException war das meine ich).
Somit wollte ich dann in der Methode erst testen, ob sich der Client erfolgreich mit dem Server verbinden konnte und eine Variable setzen, die den status merkt.
Das selbe dann wenn der Client beendet wird. Dort wollte ich dann nachsehen, ob der Client verbunden ist und die Events deregistrieren.

Aber gut, ich kann das ja auch über Exception behandeln.

Grüße Stephan

L
667 Beiträge seit 2004
vor 13 Jahren

Ich hab mich ja schon vor langer Zeit von diesem Remoting-Murks verabschiedet also bin ich da sicherlich kein "Experte" in dem Bereich (Gott sei dank...) - aber gab es bei Remoting nicht auch einen Modus, bei dem die Verbindung dauerhaft offen bleibt ?

Stichwort Lifetimeservice oder so was ?

"It is not wise to be wise" - Sun Tzu

3.728 Beiträge seit 2005
vor 13 Jahren
Gefährliches Halbwissen

LifetimeService steuert die Lebenszeit des Objekts, nicht die der Socketverbindung!

Von Murks kann übrigens nicht die Rede sein. Allerdings tun sich Leute, die gewohnt sind direkt auf Socket-Ebene zu arbeiten, mit Remoting schwer, da Remoting die Netzwerkkommunikation komplett kapselt. Diese Leute haben dann das Gefühl nicht mehr die Kontrolle zu haben oder fühlen sich vom Remoting-Framework bevormundet.

Aus dem selben Grund gibt es auch Leute, die ihr Datenbanksystem selber schreiben.

L
667 Beiträge seit 2004
vor 13 Jahren

Auf so eine Idee würde ich nur dann kommen, wenn mir alle bestehenden Datenbanksysteme vorschreiben würden, dass ich einen string Wert nur in einer Tabelle speichern darf, wenn ich vorher 5 integers und 3 datetimes speichere, anschließend 2 bool Werte auslese und danach eine Tabelle löschen muss.

Wenn es dann noch weiterhin die Einschränkung gibt, dass der String an der 5. Stelle immer zwingend ein "X" haben muss, dann würde ich die Idee wohl in die Tat umsetzen. Ähnlich verhält es sich mit Remoting...

"It is not wise to be wise" - Sun Tzu

Hinweis von gfoidl vor 13 Jahren

Vorsorglicher Hinweis: Bitte bleibt beim Thema. Danke.

3.728 Beiträge seit 2005
vor 13 Jahren
Abstraktion

Remoting ist eine Technologie um entfernte Methodenaufrufe durchzuführen. Ein Client ruft dabei eine beliebige Methode eines Objekts auf, welches auf einem Server lebt. Beschränkungen gibt es dabei nicht, außer dass das Objekt auf dem Server direkt oder indirekt von MarshalByRefObj abgeleitet sein muss.

Remoting versucht die Netzwerkkommunikation so weit wie irgend möglich zu kapseln. Wer RPC machen will, der möchte, dass sich die Methodenaufrufe wie lokale Stack basierte Aufrufe anfühlen. Man möchte sich nicht mit Sockets und den darunterliegenden Protokollen beschäftigen müssen, deshalb entscheidet man sich für RPC mit Remoting.

Wer direkt Einfluss auf die Netzwerkkommunikation nehmen möchte, der sollte sich nicht für Remoting entscheiden. Dafür gibt es die Tools aus dem System.Net Namensraum. Damit kann man alles machen, was im Rahmen der Netzwerkprotokolle möglich ist. Dafür ist die Implementierung wesentlic aufwändiger. Ob Socket basierte Netzwerkprogrammierung nötig ist, muss jeder selber für sein konkretes Projekt entscheiden.

Wenn Dir Remoting zu viele Beschränkungen hat, dann trifft das wohl auch für WCF zu, denn auch WCF ist eine RPC-Technologie, welche die Netzwerkkommunikation kapselt.

L
667 Beiträge seit 2004
vor 13 Jahren

WCF finde ich zumindest angenehmer zu nutzen, wobei ich dazu sagen muss, dass ich es noch nie in einem Projekt gebraucht habe, da sich meine Netzwerk-Klassen mittlerweile in mehreren Großprojekten, sowohl was die Performance als auch die Flexibilität angeht, bewährt haben und ich keinen Grund sehe, jetzt WCF auszuprobieren.
Zumindest muss man bei WCF keine 20 kryptischen Konfigurationsstrukturen befüllen - teilweise mit untypisierten Listen, in denen bestimmte Objekte in der richtigen Reihenfolge drin stecken müssen - um überhaupt eine Connection hinzubekommen. Auch callbacks / events scheinen mit WCF mit deutlich weniger Daumenschrauben nutzbar zu sein als bei Remoting. Insofern zumindest was die Usability angeht ein Schritt in die richtige Richtung.

"It is not wise to be wise" - Sun Tzu

3.728 Beiträge seit 2005
vor 13 Jahren

WCF finde ich zumindest angenehmer zu nutzen, wobei ich dazu sagen muss, dass ich es noch nie in einem Projekt gebraucht habe ...

Remoting lässt sich sehr einfach einsetzen. Man muss nicht, wie bei WCF an den richtigen Stellen die richtigen Attribute setzen. Auch mit Vererbung gibt es keine Probleme, da Remoting im Gegensatz zu WCF von einer heilen 100% .NET Welt ausgeht. Hier ein kleines Beispiel wie leicht und intuitiv der Einsatz von Remoting sein kann: Remoting-Helfer

..., da sich meine Netzwerk-Klassen mittlerweile in mehreren Großprojekten, sowohl was die Performance als auch die Flexibilität angeht, bewährt haben und ich keinen Grund sehe, jetzt WCF auszuprobieren.

Das finde ich völlig okay. Aber es ist ein Unterschied ob man die bewährten Klassen schon hat, oder noch vor der Wahl der Kommunikationstechnologie steht, für ein Projekt, welches noch gar nicht existiert. Da kommt man meistens schneller zu guten Ergebnissen, wenn man etwas fertiges "von der Stange" nimmt.

Zumindest muss man bei WCF keine 20 kryptischen Konfigurationsstrukturen befüllen - teilweise mit untypisierten Listen, in denen bestimmte Objekte in der richtigen Reihenfolge drin stecken müssen - um überhaupt eine Connection hinzubekommen.

Du meinst damit vermutlich die Hashtable, die zur Übergabe von Channel-Einstellungen verwent wird. Das muss man nicht so machen! Es geht auch alles per App.config. Ist auch seit .NET 2.0 sehr gut dokumentiert (das war früher allerdings nicht so) MSDN: Schema für Remoteeinstellungen.
Aber selbst wenn Du die Konfiguration per Code machst, spielt die Reihenfolge der Einstellungen in der Hashtable keine Rolle.

Was WCF angeht, muss ich Dir wiedersprechen. Die Konfiguration von WCF ist sehr komplex und alles andere als intuitiv. Schau Dir mal das Konfigurationsschema von WCF hier an MSDN: WCF Konfigurationsschema und vergleiche es mit dem oben von Remoting. Von "angenehmer" kann da nicht die rede sein (zumindest wenn man über "Hello World" hinausgeht).

Versteh mich nicht falsch. WCF ist nicht schlecht. Vor allem, wenn man interoperabel sein muss oder generell Internet-Anwendungen erstellt. Für einfache .NET zu .NET Kommunikation ist es aber viel zu umständlich und erlegt dem Entwickler entkoppeltes Programmiermodell auf, was bei einer großen heterogenen Anwendung zwar absolut sinnvoll ist, aber im .NET zu .NET LAN-Szenario nur unnötige Komplexität und damit Kosten mit sich bringt.

Auch callbacks / events scheinen mit WCF mit deutlich weniger Daumenschrauben nutzbar zu sein als bei Remoting. Insofern zumindest was die Usability angeht ein Schritt in die richtige Richtung.

Das kommt auf den Blickwinkel an. Bei Remoting funktionieren Callbacks automatisch, ohne dass man etwas tun muss (außer clientseitig einen TcpChannel statt eines TcpClientChannel zu registrieren). Bei WCF muss man für jeden Callback explizit Code hinschreiben. WCF raubt so einiges an Flexibilität.
Von Daumenschrauben kann bei Remoting also nicht die Rede sein, sondern eher bei WCF. Remoting zwingt einem weder dazu irgendwelche Maximalwerte für Message Quotas einzuhalten, noch Kopfstände wegen Callbacks zu machen, noch sonst was. Remoting funktioniert einfach und unkompliziert.

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Die Konfiguration von WCF ist sehr komplex und alles andere als intuitiv.

Stimmte bis zu WCF 4 hundertprozentig 😉
Es hat sich aber einiges getan und für die meisten Anwendungsfälle ist nun gar keine Konfiguration mehr notwendig da ein Default verwendet wird. Siehe auch A Developer's Introduction to Windows Communication Foundation 4.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

3.728 Beiträge seit 2005
vor 13 Jahren
Wcf4

Hallo gfoidl,

oh, das wusste ich noch nicht. Feine Sache!

Danke für den Hinweis.