Compartir a través de


Ejemplo de comunicación remota: CallContext

Este tema es específico de una tecnología heredada que se mantiene para la compatibilidad con versiones anteriores con aplicaciones existentes y no se recomienda para nuevo desarrollo. Las aplicaciones distribuidas se deberían desarrollar utilizando  Windows Communication Foundation (WCF).

Este ejemplo utiliza la clase CallContext y la interfaz ILogicalThreadAffinative para pasar los datos entre una aplicación de cliente remoto y una aplicación de servidor remoto.

Esta aplicación se ejecuta en un solo equipo o a través de una red. Si desea ejecutar esta aplicación a través de una red, debe reemplazar “host local” en la configuración del cliente por el nombre del equipo remoto.

6z5ezzh0.Caution(es-es,VS.100).gifPrecaución:
.NET Remoting no lleva a cabo la autenticación o el cifrado de forma predeterminada. Por consiguiente, se recomienda que dé todos los pasos necesarios para asegurarse de la identidad de los clientes o de los servidores antes de interactuar de forma remota con ellos. Dado que las aplicaciones de .NET Remoting exigen permisos FullTrust para ejecutarse, si a un cliente no autorizado se le permitiera el acceso a su servidor, el cliente podría ejecutar el código como si fuese un cliente de plena confianza. Autentique siempre a sus clientes y cifre las secuencias de comunicación. Para obtener más información, vea Seguridad en comunicación remota.

Para compilar este ejemplo

  1. Escriba los siguientes comandos en el símbolo del sistema:

    vbc /r:System.Runtime.Remoting.dll /t:library MyRemoteType.vb
    vbc /r:System.Runtime.Remoting.dll /r:MyRemoteType.dll client.vb
    vbc /r:System.Runtime.Remoting.dll /r:MyRemoteType.dll server.vb
    
    csc /r:System.Runtime.Remoting.dll /t:library MyRemoteType.cs
    csc /r:System.Runtime.Remoting.dll /r:MyRemoteType.dll client.cs
    csc /r:System.Runtime.Remoting.dll /r:MyRemoteType.dll server.cs
    

MyRemoteType

Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Messaging

Namespace [Shared]
    Public Class MyRemoteType
    Inherits MarshalByRefObject

    Private starttime As DateTime

    Public Sub New()
        Console.WriteLine("A MyRemoteObject instance has been created.")
        starttime = DateTime.Now
    End Sub

    Protected Overrides Sub Finalize()
        Console.WriteLine("MyRemoteObject being collected after " & (New TimeSpan(DateTime.Now.Ticks - starttime.Ticks)).ToString() & " seconds.")
    End Sub

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

        ' This call overwrites the client's CallContextString.
        CallContext.SetData("ServerThreadData", New CallContextString("This is the server side replacement."))
        Return DateTime.Now
    End Function
End Class

'  One method of communicating between client and server is 
'  to use the CallContext. Calling CallContext.SetData essentially puts the data
'  in a Thread Local Store. This means that the information is available 
'  to that thread or that "logical" thread (across application domains) only.
<Serializable()> _
Public Class CallContextString
    Implements ILogicalThreadAffinative

    Dim _str As String = ""

    Public Sub New(ByVal str As String)
        _str = str
        Console.WriteLine("CallContextString created.")
    End Sub

    Public Overrides Function ToString() As String
        Return _str
    End Function
End Class
End Namespace
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;

namespace Shared
{
    public class MyRemoteType : MarshalByRefObject 
    {
        private DateTime starttime;

        public MyRemoteType()
        {
            Console.WriteLine("A MyRemoteObject instance has been created.");
            starttime = DateTime.Now;
        }

        ~MyRemoteType()
        {
            Console.WriteLine("MyRemoteObject being collected after " + (new TimeSpan(DateTime.Now.Ticks - starttime.Ticks)).ToString() + " seconds.");
        }

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

            // This call overwrites the client's CallContextString.
            CallContext.SetData("ServerThreadData", new CallContextString("This is the server side replacement."));
            return DateTime.Now;
        }
    }

    //  One method of communicating between client and server is 
    //  to use the CallContext. Calling CallContext.SetData essentially puts the data
    //  in a Thread Local Store. This means that the information is available 
    //  to that thread or that "logical" thread (across application domains) only.
    [Serializable]
    public class CallContextString : ILogicalThreadAffinative
    {
        String _str = "";

        public CallContextString(String str)
        {
            _str = str;
            Console.WriteLine("CallContextString created.");
        }

        public override String ToString()
        {
            return _str;
        }
    }
}

Client

Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http
Imports System.Runtime.Remoting.Contexts
Imports System.Runtime.Remoting.Messaging
Imports [Shared]

Public Class Client
    Public Shared Sub Main()
        ' Register Channel
        Dim channel As HttpChannel = New HttpChannel()
        ChannelServices.RegisterChannel(channel, False)

        ' Register MyRemoteObject
        RemotingConfiguration.RegisterWellKnownClientType( _
                GetType(MyRemoteType), _
                "https://localhost:8080/MyRemoteObject")

        ' Add a CallContextString object to the call context
        CallContext.SetData("ServerThreadData", New CallContextString("This is the thread data inserted on the client thread."))

        Console.WriteLine("CallContextString prior to the call: " & CallContext.GetData("ServerThreadData").ToString())
        Dim service As MyRemoteType = New MyRemoteType()
        Console.WriteLine("Server time is: " & service.GetServerTime().ToLongTimeString())
        Console.WriteLine("CallContextString after the call: " & CallContext.GetData("ServerThreadData").ToString())
    End Sub
End Class
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using Shared;

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

            // Register MyRemoteObject
            RemotingConfiguration.RegisterWellKnownClientType(
                typeof(MyRemoteType),
                "https://localhost:8080/MyRemoteObject");

            // Add a CallContextString object to the call context
            CallContext.SetData("ServerThreadData", new CallContextString("This is the thread data inserted on the client thread."));

            Console.WriteLine("CallContextString prior to the call: " + CallContext.GetData("ServerThreadData").ToString());
            MyRemoteType service = new MyRemoteType();
            Console.WriteLine("Server time is: " + service.GetServerTime().ToLongTimeString());
            Console.WriteLine("CallContextString after the call: " + CallContext.GetData("ServerThreadData").ToString());
        }
    }
}

Server

Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http
Imports [Shared]

Public Class Server

    Public Shared Sub Main()
        ' Register channel
        Dim channel As HttpChannel = New HttpChannel(8080)
        ChannelServices.RegisterChannel(channel, False)

        ' Register MyRemoteObject
        RemotingConfiguration.RegisterWellKnownServiceType( _
            GetType(MyRemoteType), _
            "MyRemoteObject", _
            WellKnownObjectMode.SingleCall)

        Console.WriteLine("Press enter to stop this process.")
        Console.ReadLine()
    End Sub

End Class
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Shared;

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

            // Register MyRemoteObject
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(MyRemoteType),
                "MyRemoteObject",
                WellKnownObjectMode.SingleCall);

            Console.WriteLine("Press enter to stop this process.");
            Console.ReadLine();
        }
    }
}

Vea también

Otros recursos

Ejemplos de comunicación remota