.NET Remoting过时了吗?为什么公司的项目还是选择用.NET Remoting,而不是WCF?

近两年看到很多介绍WCF分布式开发的文章,很少看到有深入介绍.NET Remoting开发的文章,似乎Remoting技术逐渐从大众的视野中消失了一样。自从2005年发布这个名称为Indigo的技术以来,WCF逐渐成为.NET分布式开发的事实标准。然后微软没有推崇和更新的技术,像我们这样的第三世界国家,唯微软马首是瞻,也纷纷转向WCF技术的实践与开发。近期看到世界对SilverLight技术前展的担忧,就看到很明显的倾向。一个以擅长开发平台(Platform,.NET)和开发工具(Visual Studio,SQL Sever)的公司,居然也能控制大量的中下游开发商的技术选择倾向,一想到最近在做的工作流WF的升级(.NET 3.0到.NET 4.0)的尴尬处境,令人叹息不已,这也许是IT产业链的特色。

 

我要提出的的观点是,作为通讯技术架构的.NET Remoting,并没有从我们的视野中消失,反而有很多产品还是继续使用和维护以.NET Remoting作为通讯架构方式。我所看到的产品,是上市公司的产品,年收入是百万级别的产品,不用怀疑它是小企业的小应用。所以,我要讨论一下,为什么.NET Remoting没有过时,更没有out。

先来看一下,要能成为企业应用的通讯架构技术基础,要满足的条件

  • 被传送的对象,消息(.NET Message)要容易定义,格式通用,灵活
  • 传递消息的方式,通常叫Channel, 灵活,支持各种应用环境,比如局域网选择TCP,互联网选择HTTP,进程间的通讯可选择Named Pipes或MSMQ。
  • 被使用的服务(Services)要容易定义,并且可以灵活选择通道和消息格式

抽象的说了这几点,不容易理解,来举例说明。在ERP系统中,是如何做到简单灵活的应用通讯技术的。以销售系统为例子,来看看它的架构方式。

 

消息格式定义  销售单

[Serializable]
public partial class SalesOrderEntity : CommonEntityBase
{
   public virtual System.String PriceCode
        {
            get { return (System.String)GetValue((int)SalesOrderFieldIndex.PriceCode, true); }
            set    { SetValue((int)SalesOrderFieldIndex.PriceCode, value); }
        }


public virtual System.String VendorNo
        {
            get { return (System.String)GetValue((int)SalesOrderFieldIndex.VendorNo, true); }
            set    { SetValue((int)SalesOrderFieldIndex.VendorNo, value); }
        }

}

销售单只举例了两个属性,卖价编码和供应商商编码,在定义实体时,加Serializable特性表示可以序列化传递。

服务接口定义 保存销售单

public interface ISalesOrderManager
{
        SalesOrderEntity SaveSalesOrder(SalesOrderEntity salesOrder);
}

服务实现 保存销售单

public sealed partial class SalesOrderManager : ISalesOrderManager
{
        public SalesOrderEntity SaveSalesOrder(SalesOrderEntity salesOrder)
        {
           .....
        }
}

应用服务,保存销售单的窗体

ISalesOrderManager salesOrderManager = ClientProxyFactory.CreateProxyInstance<ISalesOrderManager>();

这就是所有的代码,从销售单的消息格式定义到定义服务和接口与实现,最后是如何应用服务,这四块代码,包含了上面所讲的全部内容,而它的实现,就是运用.NET Remoting来作为通讯技术平台。

我想肯定有很多第三方的工具厂商,也已经实现类似于.NET Remoting和WCF的的通讯框架,但是考虑到成本(cost),效率,可维护性,WCF和.NET Remoting是免费的,不需要任何成本,普及性好,名家出身,这会排挤大量的中小企业的商业的通讯框架。

 

从上面的代码可以看出来,一部分是标准的做法,定义接口和实现,另一部分,有一个关键的类型ClientProxyFactory,来充当了通讯的桥梁,它就是基于.NET Remoting技术而构建的通讯框架。这个框架可以处理好下面的场景:

1  客户端的连接,服务器要能控制。服务器可以控制是否接受客户端的连接请求,以保证系统不会负荷过载。

2  服务器崩溃,客户端要得到通知,并能重新连接。这一点很重要。服务器因各种原因停止运行后,客户端要可以马上得到消息,并保存当前操作,阻止用户继续使用系统。试想一下,服务器因为断电停止运行后,客户端程序还在继续输入销售单,当用户准备保存时,却又提示服务器拒绝请求。

3 可以打包数据,加密,到服务器段解析出来。对于重要的数据,这个功能点很重要。

4 并发控制,控制可以并发使用的用户数量。同时在线的用户,允许执行的功能,服务器都有记录。

5 安全控制,阻止其它类型的应用程序连接服务器,防止攻击

6 传送功能 客户端向服务器,传送大文件,传送图片,传送需要的内容,文字,传送错误报告,传送截屏。

7 广播功能,一个客户端可以向连接中的其它所有客户端传送消息。比如,ERP系统管理员,可以通知所有的正在连接并使用系统的用户,暂时退出,需要更新系统。服务器可以对所有客户端广播,前面提到的服务器停止运行,所有客户端要中断运行,也是服务器向客户端的广播。

有了这么多的现成的解决方案,所以公司的通讯框架一直都是用.NET Remoting,而不会升级到WCF。而且一旦稳定之后,把.NET Remoting技术升级为另一种技术WCF,对系统而言,简直是一场灾难。要知道,大量的测试,是通过一个个byte来比较过的,确认无误的才投入使用。

如果你有基于WCF的成熟的通讯架构的应用,应该把它应用到产品中,并且不断的改善,精进。如果没有,我还是推荐你看一下那7条需求列表,对比一下,如何在WCF或是Remoting技术来实现它,应用它,而不是总在说WCF是如何的好,如何的灵活方便。我研究了WCF之后,反而觉得它太灵活了,需要你做出选择的地方太多了。这并不总是好事情。

 

在升级WCF时,我遇到这个问题,与你分享我的经验。在.NET Remoting中,标准的接口定义成这样:

public interface IVendorManager
{
        VendorEntity GetVendor(String VendorNo);
        VendorEntity GetVendor(String VendorNo, IPrefetchPath2 prefetchPath);
}

把它升级成WCF的接口,就要这样:

[ServiceContract()]
[ServiceKnownType(typeof(VendorEntity))]    
public interface IVendorManager
{
         [OperationContract(Name = "VendorNo")]
         VendorEntity GetVendor(String VendorNo);
         [OperationContract(Name = "VendorNoPrefetchPath")]
         VendorEntity GetVendor(String VendorNo,IPrefetchPath2 prefetchPath);
}

原因是WCF不支持方法重载(overload),要加上Name特性才行。现在,要变成WCF方式的调用,这样的代码就跑不通,

IVendorManager  vendorManager = ClientProxyFactory.CreateProxyInstance<IVendorManager>();
VendorEntity express=vendorManager.GetVendor(“DHL”);

因为在WCF中,给一个参数的GetVendor方法加了别名为VendorNo,它的调用应该是这样的:

VendorEntity express=vendorManager.VendorNo(“DHL”);

框架是运行时来绑定的,而在编译时,我又不希望WCF来帮忙我生成IVendorManager接口的VendorNo方法,

那上面的代码就无法通过编译,要用到反射,获取GetVendor的特性VendorNo值,并以VendorNo为方法名来调用。这样,客户端接口不用做任何改变,就可以把.NET Remoting升级到WCF,秘密全都在ClientProxyFactory类型的CreateProxyInstance方法里面,也就是一个成熟的通讯框架。

读过这篇文章后,你或许可以体会到了,把系统从.NET Remoting升级到WCF,客户端代码几乎不用改动,很有效率。

读大学时,看到设计模式的作者,推荐按照接口编程,我也向你推荐这种方式,按照接口编程。

posted @ 2011-09-20 09:17  信息化建设  阅读(19395)  评论(30编辑  收藏  举报