リモート処理の例 : CallContext

このトピックの対象は、既存のアプリケーションとの下位互換性のために残されているレガシ テクノロジに特定されています。新規の開発には、このトピックを適用しないでください。分散アプリケーションは、現在は Windows Communication Foundation (WCF) を使用して開発する必要があります。

このサンプルでは、CallContext クラスおよび ILogicalThreadAffinative インターフェイスを使用して、リモート処理クライアント アプリケーションとリモート処理サーバー アプリケーション間でデータの受け渡しを行います。

このアプリケーションは、1 台のコンピューター上で、またはネットワーク経由で実行されます。このアプリケーションをネットワーク上で実行する場合、クライアント構成内の "localhost" をリモート コンピューターの名前に置き換える必要があります。

6z5ezzh0.Caution(ja-jp,VS.100).gif注意 :
.NET リモート処理は、既定では認証も暗号化も行いません。したがって、クライアントやサーバーとリモートで通信する前に、ID の確認に必要な手順をすべて実行することをお勧めします。.NET リモート処理アプリケーションの実行には、FullTrust アクセス許可が必要です。認証されていないクライアントがサーバーへのアクセスを許可された場合は、完全に信頼されているものとして、コードを実行できます。常に、クライアントを認証し、通信ストリームを暗号化してください。詳細については、「リモート処理でのセキュリティ」を参照してください。

このサンプルをコンパイルするには

  1. コマンド プロンプトで次のコマンドを入力します。

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

クライアント

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

サーバー

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

参照

その他のリソース

リモート処理の例