Partager via


Exemple de communication à distance : CallContext

Cette rubrique est spécifique à la technologie héritée assurant la compatibilité descendante avec des applications existantes et n'est pas recommandée en cas de nouveau développement. Les applications distribuées doivent maintenant être développées à l'aide de Windows Communication Foundation (WCF)

Cet exemple utilise la classe CallContext et l'interface ILogicalThreadAffinative pour passer des données entre une application cliente de communication à distance et une application serveur de communication à distance.

Cette application peut s'exécuter sur un seul ordinateur ou sur un réseau. Pour exécuter cette application sur un réseau, remplacez « localhost » dans la configuration client par le nom de l'ordinateur distant.

6z5ezzh0.Caution(fr-fr,VS.100).gifAttention :
Par défaut, .NET Remoting ne procède ni à l'authentification ni au chiffrement. Par conséquent, il est recommandé que vous preniez toutes les mesures nécessaires à l'identification des clients et des serveurs avant d'interagir à distance avec eux. Comme les applications .NET Remoting requièrent des autorisations FullTrust pour s'exécuter, un client non autorisé pourrait exécuter du code comme s'il était d'un niveau de confiance suffisant s'il se voyait accorder l'accès à votre serveur. Veillez à toujours authentifier vos clients et à chiffrer les flux de données de communication. Pour plus d'informations, consultez Sécurité dans la communication à distance.

Pour compiler cet exemple

  1. À l'invite de commandes, tapez les commandes suivantes :

    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();
        }
    }
}

Voir aussi

Autres ressources

Exemples de communication à distance