WCf是集大成者,具備其餘微軟的不少技術,其中分佈式上不少藉助於Remoting,因此研究一下Remoting有助於理解WCF 跨域
提到Remoting就不得不涉及到MarshalByRefObject這個對象,網絡上對這個詞語的解釋很是的模糊不清,特別是說「跨域訪問,Remoting是引用傳遞,不是值傳遞」,而沒有講「引用傳遞」究竟是傳的什麼東西,有的地方確實說了經過ObjRef對象 傳遞須要交互的全部內容信息,可是更多的是對「引用傳遞」沒有清楚的認識,或者說是經過其餘方式來理解「引用傳遞」而不是經過「引用傳遞」來更好的理解Remoting,這種邏輯思惟方式,特別容易產生囫圇吞棗的模糊概念,看似明白,其實不明白。 網絡
爲了理解引用傳遞,寫了一個例子,可能有助於理解 代碼 tcp
定義Interface 分佈式
public interface IPersonService { String HelloMethod(String name); }
定義 Implementspa
public class PersonService : MarshalByRefObject, IPersonService { public String HelloMethod(String name) { Console.WriteLine( "Server Hello.HelloMethod : {0}", name); return "Hi there " + name; } }
static void Main(string[] args) { //TCP協議傳輸消息的信道實現 TcpChannel chan1 = new TcpChannel(8085); //爲遠程調用實現使用HTTP協議傳輸消息的客戶端通道 HttpChannel chan2 = new HttpChannel(8086); //提供幫助進行遠程處理信道註冊、解析和URL發現的靜態方法。沒法繼承此類 ChannelServices.RegisterChannel(chan1, false); ChannelServices.RegisterChannel(chan2, false); //提供多種配置遠程結構的靜態方法 RemotingConfiguration.RegisterWellKnownServiceType ( //typeof(HelloServer), typeof(PersonService), "SayHello", WellKnownObjectMode.Singleton ); System.Console.WriteLine("Press Enter key to exit"); System.Console.ReadLine(); }
class Program { static void Main(string[] args) { TcpChannel chan1 = new TcpChannel(); ChannelServices.RegisterChannel(chan1,false); //Activator包含特定的方法,用以在本地或從遠程建立對象類型、或獲取對現有遠程對象的引用。沒法繼承此類 IPersonService obj1 = (IPersonService)Activator.GetObject( typeof(IPersonService),// typeof(HelloServer), "tcp://localhost:8085/SayHello"); if (obj1 == null) { System.Console.WriteLine( "Could not locate TCP server"); } //使用HTTP通道獲得遠程對象 HttpChannel chan2 = new HttpChannel(); ChannelServices.RegisterChannel(chan2,false); IPersonService obj2 = (IPersonService)Activator.GetObject( typeof(IPersonService),// typeof(HelloServer), "http://localhost:8086/SayHello"); if (obj2 == null) { System.Console.WriteLine( "Could not locate HTTP server"); } Console.WriteLine( "Client1 TCP HelloMethod {0}", obj1.HelloMethod("Caveman1")); Console.WriteLine( "Client2 HTTP HelloMethod {0}", obj2.HelloMethod("Caveman2")); Console.ReadLine(); } }
注意,客戶端使用的 「IPersonService」接口,對於客戶端來說是不知道接口的實例類的,代理
客戶端方法的調用也只是經過Activator生成的代理對象把調用的信息、連接信息等等進行打包,code
服務端接收到打包過來的信息後,根據打包信息內容,對相應的類和方法進行操做,好比:建立(調用)服務實體,對方法進行調用,把返回值進行打包並傳輸給客戶端端,裏邊具體的邏輯還須要繼續研究server
這裏只想說明一點,「Remoting傳輸的引用」,究竟是什麼意思,省得誤解。對象