程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> .NET Remoting過時了嗎?為什麼公司的項目還是選擇用.NET Remoti

.NET Remoting過時了嗎?為什麼公司的項目還是選擇用.NET Remoti

編輯:關於C#
 

近兩年看到很多介紹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,客戶端代碼幾乎不用改動,很有效率。

讀大學時,看到設計模式的作者,推薦按照接口編程,我也向你推薦這種方式,按照接口編程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved