.NET Remoting

轉自: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。

原始程式碼下載

你可能感兴趣的:(.net)