(文/金延涛)
1.remoting技术的特点
remoting技术可以为分布式应用提供强有力的支持,我们可以根据需求和特定的环境选择合适的通道和序列化的方式满足我们的应用。另外remoting技术具有非常好的扩展特性,我们甚至可以在remoting体系结构的每个组件上进行扩展和自定义来满足丰富的应用需求。
2.环境分析
网络环境分析
假设公司是一家大型机构,内部出于安全的需要,不同的部门和不同的子部分可能被不同的网络防火墙隔离,但是不同的部门或者子部门需要共同协作来管理一些应用,因此我们可能需要穿越公司内部的防火墙来满足我们的应用需要。
软件环境分析
假设公司的大部分应用建立在windows平台之上,软件大多运行在clr之上,开发架构采用主流的三层架构,服务方式采用c/s架构,出于安全考虑,公司拒绝非服务器IP直接访问生产数据库,同时可以预见的是需要处理大数据量,所以我们需要提供分布式处理来满足公司安全方面的要求和达到良好的性能要求。
3.remoting架构设计
通道选择、激活方式、对象调用方式、传输方式选择
由于公司内部网络环境复杂,需要有较好的适应能力,选择httpchannel作为传输通道会有比较强的网络环境适应能力;激活方式采用服务端、singleton方式激活;业务操作类使用按址列集的方式进行传输,实体对象使用按值列集的方式进行传输。
解决方案设计
在三层架构的基础上加上三个解决方案,分别为remoting服务端、remoting客户端、IDL,建议将IDL的定义和实体类类的定义放在一个解决方案中。IDL的程序接需要分别被remoting服务端、remoting客户端应用。
示例代码
IDL定义
//接口定义
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingIDL
{
public interface IService
{
OnlineOrder[] SayMessage(OnlineOrder o);
Sample SayMessage(Sample obj);
}
}
//实体类设计
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingIDL
{
[Serializable]
public class Sample
{
private string message;
public string Message
{
get { return message; }
set { message = value; }
}
}
}
业务操作类
using System;
using System.Collections.Generic;
using System.Text;
using RemotingIDL;
public class MyService : MarshalByRefObject, IService
{
public OnlineOrder[] SayMessage(OnlineOrder o)
{
List<OnlineOrder> orders = new List<OnlineOrder>();
for (int i = 0; i < 10; i++)
{
OnlineOrder order = new OnlineOrder();
order.Message = o.Message;
orders.Add(order);
}
Console.WriteLine("Record count:"+orders.Count);
return orders.ToArray();
}
public Sample SayMessage(Sample obj)
{
obj.Message = "this is a remoting invoke";
Console.WriteLine("this is a remoting serilizable!");
return obj;
}
}
服务端配置
using System;
using System.Collections.Generic;
using System.Text;
using RemotingIDL;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace RemotingServer
{
class Program
{
static void Main(string[] args)
{
HttpChannel http = new HttpChannel(81);
ChannelServices.RegisterChannel(http, false);
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyService), "MyService", WellKnownObjectMode.Singleton);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ShoppingCart), "ShoppingCart", WellKnownObjectMode.Singleton);
Console.WriteLine("Remoting is running");
Console.ReadLine();
}
}
客户端调用
using System;
using System.Collections.Generic;
using System.Text;
using RemotingIDL;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace RemotingClient
{
class Program
{
static void Main(string[] args)
{
try
{
HttpChannel http = new HttpChannel();
ChannelServices.RegisterChannel(http, false);
IShoppingCart shoppingCart = (IShoppingCart)Activator.GetObject(typeof(IShoppingCart), "http://localhost:81/ShoppingCart");
if (shoppingCart != null)
{
Product[] products = shoppingCart.GetProducts("Architecture");
Console.WriteLine("Product count:" + products.Length.ToString());
}
}
catch (System.Runtime.Serialization.SerializationException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
catch (System.ArgumentException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
Console.ReadLine();
}
}
}
4.remoting设计中遇到的问题
list传输的问题
在webservice中list在默认情况下被转换为数组进行传输,在remoting采用服务端、singleton方式激活的情况下,传输list直接抛出异常,不做默认的转换。
客户端对象传输的问题
在remoting采用服务端、singleton方式激活的情况下,客户端对象按址列集传输时直接抛出异常,按值列集传输正常。
调试问题
目前想到的调试方式:通过配置文件配置为调试状态和发布状态,在调试状态直接调用本地对象,只有在发布状态才通过remoting调用远程对象。
本人初次使用remoting技术解决应用需求的问题,还请大家多提宝贵意见,在此谢过了!
示例代码下载:RemotingEA.rar