Share via


Remotingbeispiel: Dynamische Veröffentlichung

Dieses Thema bezieht sich auf eine veraltete Technologie, die zum Zwecke der Abwärtskompatibilität mit vorhandenen Anwendungen beibehalten wird und nicht für die neue Entwicklung empfohlen wird. Verteilte Anwendungen sollten jetzt mit  Windows Communication Foundation (WCF) entwickelt werden.

.NET-Remoting unterstützt nur Standardkonstruktoren mit vom Server aktivierten remotefähigen Typen. Sie können die Instanz programmgesteuert veröffentlichen, um ein Objekt nach dessen Erstellung mit einem bestimmten Konstruktor zu veröffentlichen und eine umfassende Steuerung über die Veröffentlichung dieser spezifischen Instanz zu haben.

1t63e8ff.Caution(de-de,VS.100).gifVorsicht:
.NET-Remoting führt standardmäßig keine Authentifizierung oder Verschlüsselung durch. Daher empfiehlt es sich, vor der Remoteinteraktion mit Clients und Servern alle erforderlichen Schritte zu unternehmen, um die Identität der Clients oder Server zu überprüfen. Da .NET-Remoteanwendungen FullTrust-Berechtigungen zur Ausführung benötigen, könnte ein nicht autorisierter Client Code so ausführen, als ob er voll vertrauenswürdig wäre, wenn dem Client Zugriff auf Ihren Server gewährt würde. Authentifizieren Sie die Endpunkte unbedingt, und verschlüsseln Sie die Kommunikationsstreams. Weitere Informationen finden Sie unter Sicherheit beim Remoting.

So kompilieren Sie dieses Beispiel und führen es aus

  1. Geben Sie an der Eingabeaufforderung folgende Befehle ein:

    vbc -t:library remote.vb
    vbc -r:System.Runtime.Remoting.dll -r:remote.dll server.vb
    vbc -r:System.Runtime.Remoting.dll -r:remote.dll client.vb
    
    csc -t:library remote.cs
    csc -r:System.Runtime.Remoting.dll -r:remote.dll server.cs
    csc -r:System.Runtime.Remoting.dll -r:remote.dll client.cs
    
  2. Öffnen Sie zwei Eingabeaufforderungen, die auf das gleiche Verzeichnis zeigen. Geben Sie an der einen server ein. Geben Sie an der anderen client ein.

  3. Um die Veröffentlichung des remotefähigen Objekts in Phasen anzuhalten, drücken Sie EINGABETASTE an der Servereingabeaufforderung, und führen Sie den Client erneut aus, um die verschiedenen Ausnahmen zu beobachten, die in den einzelnen Phasen ausgelöst werden. Diese Anwendung wird auf einem einzelnen Computer oder über ein Netzwerk ausgeführt. Um diese Anwendung über ein Netzwerk auszuführen, müssen Sie "localhost" in der Clientkonfiguration durch den Namen des Remotecomputers ersetzen.

Remote

Imports System

Public Class ServiceClass
   Inherits MarshalByRefObject
   Private m_startTime As DateTime

   Public Sub New()
      Console.WriteLine("ServiceClass created without constructor. Instance hash is " & Me.GetHashCode().ToString())
      m_startTime = DateTime.Now
   End Sub   

   Overrides Protected Sub Finalize()
      Console.WriteLine("I'm being collected after " & (New TimeSpan(DateTime.Now.Ticks - m_startTime.Ticks)).ToString() & " seconds.")
      MyBase.Finalize()
   End Sub    

   Public Function GetServerTime() As DateTime
      Console.WriteLine("Time requested by a client.")
      Return DateTime.Now
   End Function   

   Public ReadOnly Property InstanceHash() As Integer
      Get
         Return Me.GetHashCode()
      End Get
   End Property 
End Class
using System;
using System.Collections.Generic;
using System.Text;

namespace Remote
{
    public class ServiceClass : MarshalByRefObject
    {
        private DateTime m_startTime;

        public ServiceClass()
        {
            Console.WriteLine("ServiceClass created without constructor. Instance hash is " + GetHashCode().ToString());
            m_startTime = DateTime.Now;
        }

        ~ServiceClass()
        {
            Console.WriteLine("I'm being collected after " + (new TimeSpan(DateTime.Now.Ticks - m_startTime.Ticks)).ToString() + " seconds.");
        }

        public DateTime GetServerTime()
        {
            Console.WriteLine("Time requested by a client.");
            return DateTime.Now;
        }

        public int InstanceHash
        {
            get { return GetHashCode(); }
        }
    }
}

Server

Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http

Module Module1

  Sub Main()
    Dim channel As New HttpChannel(8080)
    ChannelServices.RegisterChannel(channel, False)

    Dim object1 As New ServiceClass()

    ' Creates the single instance of ServiceClass. All clients
    ' will use this instance.
    Dim ref1 As ObjRef = RemotingServices.Marshal(object1, "object1uri")
    Console.WriteLine("ObjRef.URI: " & ref1.URI)

    Console.WriteLine("Running. Press Enter to end publication.")
    Console.ReadLine()

    ' This unregisters the object from publication, but leaves
    ' the channel listening.
    RemotingServices.Disconnect(object1)
    Console.WriteLine()
    Console.WriteLine("Disconnected the object. Client now receives a RemotingException.")
    Console.WriteLine("Press Enter to unregister the channel.")
    Console.ReadLine()
    ' At this point, the ServerClass object still exists. The server
    ' could republish it.

    ' This unregisters the channel, but leaves the application 
    ' domain running.
    ChannelServices.UnregisterChannel(channel)
    Console.WriteLine("Unregistered the channel. Client now receives a WebException.")
    ' The ServerClass object still exists. The server could
    ' reregister the channel and republish the object.
    Console.WriteLine("The host application domain is still running. Press Enter to stop the process.")
    Console.ReadLine()

    ' The ServiceClass object's Finalize method writes a message to
    ' the console. A single object will almost always succeed in 
    ' running its Finalize method before the Console is finalized;
    ' in a larger application, you could ensure that all objects 
    ' finalize before the application ends by calling the garbage 
    ' collector and waiting.
    GC.Collect()
    GC.WaitForPendingFinalizers()
  End Sub
End Module
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Remote;

namespace Server
{
    class Server
    {
        static void Main(string[] args)
        {
            HttpChannel channel = new HttpChannel(8080);
            ChannelServices.RegisterChannel(channel, false);

            ServiceClass object1 = new ServiceClass();

            // Creates the single instance of ServiceClass. All clients
            // will use this instance.

            ObjRef ref1 = RemotingServices.Marshal(object1, "object1uri");
            Console.WriteLine("ObjRef.URI: " + ref1.URI);

            Console.WriteLine("Running. Press Enter to end publication.");
            Console.ReadLine();

            // This unregisters the object from publication, but leaves
            // the channel listening.
            RemotingServices.Disconnect(object1);
            Console.WriteLine();
            Console.WriteLine("Disconnected the object. Client now receives a RemotingException.");
            Console.WriteLine("Press Enter to unregister the channel.");
            Console.ReadLine();

            // At this point, the ServerClass object still exists. The server
            // could republish it.

            // This unregisters the channel, but leaves the application 
            // domain running.
            ChannelServices.UnregisterChannel(channel);
            Console.WriteLine("Unregistered the channel. Client now receives a WebException.");

            // The ServerClass object still exists. The server could
            // reregister the channel and republish the object.
            Console.WriteLine("The host application domain is still running. Press Enter to stop the process.");
            Console.ReadLine();

            // The ServiceClass object's Finalize method writes a message to
            // the console. A single object will almost always succeed in 
            // running its Finalize method before the Console is finalized;
            // in a larger application, you could ensure that all objects 
            // finalize before the application ends by calling the garbage 
            // collector and waiting.
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}

Client

Imports System 
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp
Imports System.Runtime.Remoting.Channels.Http

Public Class ClientProcess
   <MTAThread()> _
   Public Shared Sub Main()
      
      Dim channel As New HttpChannel(0)
      ChannelServices.RegisterChannel(channel, False)

      ' Registers the remote class. (This could be done with a
      ' configuration file instead of a direct call.)
      RemotingConfiguration.RegisterWellKnownClientType(Type.GetType("ServiceClass, remote"), "https://localhost:8080/object1uri")

      ' Instead of creating a new object, this obtains a reference
      ' to the server's single instance of the ServiceClass object.
      Dim object1 As ServiceClass = New ServiceClass()

      Try
         Console.WriteLine("ServerTime: " & object1.GetServerTime())
      Catch ex As Exception
         Console.WriteLine("Exception of type: " & ex.GetType.ToString & " occurred.")
         Console.WriteLine("Details: " & ex.Message)
      End Try

   End Sub     
End Class   
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using Remote;

namespace Client
{
    public class ClientProcess
    {
  [MTAThread]
        public static void Main(string[] args)
        {
            HttpChannel channel = new HttpChannel();
            ChannelServices.RegisterChannel(channel, false);

            // Registers the remote class. (This could be done with a
            // configuration file instead of a direct call.)
            RemotingConfiguration.RegisterWellKnownClientType(
                Type.GetType("Remote.ServiceClass, remote"),
                "https://localhost:8080/object1uri");

            // Instead of creating a new object, this obtains a reference
            // to the server's single instance of the ServiceClass object.
            ServiceClass object1 = new ServiceClass();

            try
            {
                Console.WriteLine("ServerTime: " + object1.GetServerTime());
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception of type: " + ex.ToString() + " occurred.");
                Console.WriteLine("Details: " + ex.Message);
            }
        }
    }
}

Siehe auch

Verweis

RemotingServices.Marshal Method
RemotingServices.Disconnect Method
ChannelServices.UnregisterChannel Method

Weitere Ressourcen

Remotingbeispiele