轉自:http://www.iiiedu.org.tw/knowledge/knowledge20030430_2.htm
.NET Remoting | 資策會數位教育研究所講師 董淑惠 |
| 概念簡介 微軟以往使用COM/DCOM的技術來處理分散式系統架構,透過Client端的Proxy代理程式來呼叫遠端Server機器上的物件。.NET Framework則使用.NET Remoting或Web Services技術來實作分散式處理的工作概念;在此針對.NET Remoting的設計架構做一個初步的簡介。
.NET Framework提供了多種的機制來支援Remoting,如: .利用Channel來負責訊息的傳送與接收。 .利用Formatter來負責在訊息要透過channel傳送出去之前,先將訊息做適當的加密,或於訊息在透過Channel接收進來之後,先將訊息做相對的解密工作。 .利用Proxy來呼叫遠端的物件執行所要的功能呼叫。
其關係如下圖所示:
Channel 和 Formatter 在遠端物件被使用之前,必須先在Server端註冊好訊息傳送的通道(Channel),這些Channel可透過.NET Remotin configuration file或 ChannelServices物件類別的RegisterChannel方法來註冊。
在Channel的使用上,.NET Framework支援HTTP、TCP及SMTP等通道。若使用HTTP Channel ,則使用SOAP協定來收送訊息,所有的訊息會被傳送到SOAP Formatter中,被序列化(serialized)成XML的格式,而SOAP所需的headers也會被加入。至於使用TCP Channel者,則使用TCP協定來將訊息傳送到Binary Formatter中,以Binary Stream的方式來將訊息傳送到URI目的地。(URI : Universal Resource Identifier,類似大家所熟悉的URL)。
Activation and Proxy Server-Side Activation Server端在Client端要存取Remoting物件時必需在Server端能自動啟始Remoting物件,可使用RemotingConfiguration物件類別的RegisterWellKnownServiceType方法來完成這項工作。
Client-Side Activation Client端要使用遠端物件之前,可使用New 或Activator 物件類別所提供的CreateInstance或GetObject方法來啟動物件並傳回Proxy,以便Client端可透過Proxy來執行叫用遠端物件的方法。
範例 以下分三個步驟來介紹 1. 建立Remoting物件 2. 在Server上初始Remoting物件 3. Client端使用Remoting物件
步驟1:建立Remoting物件 建立一個MathServer物件類別,提供Sum方法,可給予一連串的整數由Sum方法代為計算總和。程式碼如下,並說明於後: Imports System Namespace RemotingSamples
Public Class MathServer Inherits MarshalByRefObject
Public callCounter As Integer = 0
Function Sum(ByVal ParamArray a() As Integer) As Integer Dim i As Integer For i = 0 To a.Length - 1 Sum += a(i) Next
callCounter += 1 End Function End Class
End Namespace 說明:Remoting物件必須繼承自MarshalByRefObject,如此才能透過網路,將物件執行個體的參考位置傳遞給呼叫端。
步驟2:在Server上初始Remoting物件,程式碼如下,並說明於後:
Imports System Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports System.Runtime.Remoting.Channels.Http Imports ObjectServices.RemotingSamples
Public Class Server Public Shared Sub Main() ‘建立兩個通道 Dim chan1 As New Tcp.TcpChannel(8085) Dim chan2 As New Http.HttpChannel(8086)
‘註冊要偵聽這兩個通道 ChannelServices.RegisterChannel(chan1) ChannelServices.RegisterChannel(chan2)
‘設定啟動哪個元件、服務的名稱及啟動的方式 ' 方法一 RemotingConfiguration.RegisterWellKnownServiceType( _ GetType(ObjectServices.RemotingSamples.MathServer), _ "CallMathFunction", _ WellKnownObjectMode.Singleton)
' 方法二 ' RemotingConfiguration.RegisterWellKnownServiceType( _ ' GetType(ObjectServices.RemotingSamples.MathServer), _ ' "CallMathFunction", _ ' WellKnownObjectMode.SingleCall)
Console.WriteLine("Press Enter key to exit") Console.ReadLine() End Sub End Class 說明: 1. Dim chan1 As New Tcp.TcpChannel(8085) Dim chan2 As New Http.HttpChannel(8086) 指出在8085 port上要建立TCP Channel, 8086 port上要建立Http Channel
2. ChannelServices.RegisterChannel(chan1) ChannelServices.RegisterChannel(chan2) 註冊要偵聽 Chan1 和 Chan2
3. RemotingConfiguration.RegisterWellKnownServiceType( GetType(ObjectServices.RemotingSamples.MathServer), "CallMathFunction",WellKnownObjectMode.Singleton)
指出在Server端註冊所要使用的元件、服務的名稱及啟動的方式。 其中WellKnownObjectMode.Singleton表示一個執行個體可供多個前端來呼叫,可保留其狀態,另一種則為WellKnownObjectMode.SingleCall,一個執行個體只能服務一個前端的呼叫,無法保留其狀態。
步驟3:在Client端使用Remoting物件,程式碼如下: Imports System Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports System.Runtime.Remoting.Channels.Http Imports Microsoft.VisualBasic Imports System.IO Imports ObjectServices.RemotingSamples
Public Class Client Public Shared Sub Main()
Dim counter As Integer
Dim chan1 As New TcpChannel() ChannelServices.RegisterChannel(chan1)
Dim obj1 As MathServer = _ CType(Activator.GetObject( _ GetType(ObjectServices.RemotingSamples.MathServer), _ "tcp://localhost:8085/CallMathFunction"), _ MathServer)
If (obj1 Is Nothing) Then Console.WriteLine("Could not locate TCP server") Exit Sub End If
Dim chan2 As New HttpChannel() ChannelServices.RegisterChannel(chan2)
Dim obj2 As MathServer = _ CType(Activator.GetObject( _ GetType(ObjectServices.RemotingSamples.MathServer), _ "http://localhost:8086/CallMathFunction"), _ MathServer)
If (obj2 Is Nothing) Then Console.WriteLine("Could not locate HTTP server") Exit Sub End If
Try Console.WriteLine("Client1 TCP Call Sum method {0} Counter {1}", obj1.Sum(10, 20, 30), obj1.callCounter) Console.WriteLine("Client2 HTTP HelloMethod {0} Counter {1}", obj2.Sum(100, 200, 300, 400), obj1.callCounter) Catch ioExcep As IOException Console.WriteLine("Remote IO Error" & vbCrLf & "Exception:" & vbCrLf & ioExcep.ToString()) End Try End Sub
End Class
說明: 1.Dim obj1 As MathServer = _ CType(Activator.GetObject( _ GetType(ObjectServices.RemotingSamples.MathServer), _ "tcp://localhost:8085/CallMathFunction"), _ MathServer) 在Tcp道路上叫用遠端物件(含遠端物件的物件型別名稱、URI及通道資料),透過Activator.GetObject來起始物件並傳回Proxy。
原始程式碼下載 |
|
|