`
varsoft
  • 浏览: 2435954 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics