[Remoting专题系列] 七:调用上下文

调用上下文(CallContext)提供了用于存储属性集的数据槽,可以让我们在调用服务器方法时将一些额外数据一并传送过去。当然,这些额外数据有点限制,就是必须要实现 ILogicalThreadAffinative 接口。调用上下文在应用程序域边界被克隆,其数据槽不在其他逻辑线程上的调用上下文之间共享。

我们利用这个特性写一个简单的身份验证例子。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Services;

namespace Learn.Library.Remoting
{
  
public class RemotingTest2
  
{
    
/// <summary>
    
/// 身份验证类型
    
/// </summary>

    [Serializable]
    
public class Identity : ILogicalThreadAffinative
    
{
      
private string username;
      
private string password;

      
public Identity(string username, string password)
      
{
        
this.username = username;
        
this.password = password;
      }


      
public string Username
      
{
        
get return username; }
        
set { username = value; }
      }


      
public string Password
      
{
        
get return password; }
        
set { password = value; }
      }

    }


    
/// <summary>
    
/// 远程类型
    
/// </summary>

    public class Data : MarshalByRefObject
    
{
      
public void Test()
      
{
        
// 执行身份验证      
        Identity identity = CallContext.GetData("identity"as Identity;
        
if (identity != null && identity.Username == "user1" && identity.Password == "pass")
        
{
          Console.WriteLine(
"Test AppDomain:{0}", AppDomain.CurrentDomain.FriendlyName);
        }

      }

    }


    
/// <summary>
    
/// 服务器端代码
    
/// </summary>

    static void Server()
    
{
      AppDomain server 
= AppDomain.CreateDomain("server");
      server.DoCallBack(
delegate
      
{
        TcpServerChannel channel 
= new TcpServerChannel(801);
        ChannelServices.RegisterChannel(channel, 
false);

        RemotingConfiguration.ApplicationName 
= "test";
        RemotingConfiguration.RegisterActivatedServiceType(
typeof(Data));
      }
);
    }


    
/// <summary>
    
/// 客户端代码
    
/// </summary>

    static void Client()
    
{
      TcpClientChannel channel 
= new TcpClientChannel();
      ChannelServices.RegisterChannel(channel, 
false);
      RemotingConfiguration.RegisterActivatedClientType(
typeof(Data), "tcp://localhost:801/test");

      
// 传送身份验证数据
      CallContext.SetData("identity"new Identity("user1""pass"));
      Data data 
= new Data();
      data.Test();
    }


    
static void Main()
    
{
      Server();
      Client();
    }

  }

}


数据槽中的数据可以双向传输,也就是说我们可以从服务器返回更多的信息给客户端。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Services;

namespace Learn.Library.Remoting
{
  
public class RemotingTest2
  
{
    [Serializable]
    
public class ServerTime : ILogicalThreadAffinative
    
{
      
private DateTime time;

      
public ServerTime(DateTime time)
      
{
        
this.time = time;
      }


      
public DateTime Time
      
{
        
get return time; }
      }

    }


    
/// <summary>
    
/// 远程类型
    
/// </summary>

    public class Data : MarshalByRefObject
    
{
      
public void Test()
      
{
        CallContext.SetData(
"ExInfo"new ServerTime(DateTime.Now));
        Console.WriteLine(
"Test AppDomain:{0}", AppDomain.CurrentDomain.FriendlyName);
      }

    }


    
/// <summary>
    
/// 服务器端代码
    
/// </summary>

    static void Server()
    
{
      AppDomain server 
= AppDomain.CreateDomain("server");
      server.DoCallBack(
delegate
      
{
        TcpServerChannel channel 
= new TcpServerChannel(801);
        ChannelServices.RegisterChannel(channel, 
false);

        RemotingConfiguration.ApplicationName 
= "test";
        RemotingConfiguration.RegisterActivatedServiceType(
typeof(Data));
      }
);
    }


    
/// <summary>
    
/// 客户端代码
    
/// </summary>

    static void Client()
    
{
      TcpClientChannel channel 
= new TcpClientChannel();
      ChannelServices.RegisterChannel(channel, 
false);
      RemotingConfiguration.RegisterActivatedClientType(
typeof(Data), "tcp://localhost:801/test");

      Data data 
= new Data();
      data.Test();
      Console.WriteLine((CallContext.GetData(
"ExInfo"as ServerTime).Time);
    }


    
static void Main()
    
{
      Server();
      Client();
    }

  }

}

posted on 2007-06-05 09:19  编程山人  阅读(333)  评论(0编辑  收藏  举报