初探remoting雙向通訊(一)

2022-02-03 10:14:49 字數 3718 閱讀 2569

2023年06月24日 15:47:07

喜歡特別冷的冬天下著雪

閱讀數 4389

一、從乙個小例子開始

1.0定義物件

namespace remotesample

public int sum(int a, int b)}}

將其編譯為乙個lib檔案:csc /t:library remoteobjec.cs

2.0伺服器端

using system;

using system.runtime;

using system.runtime.remoting;

using system.runtime.remoting.channels;

using system.runtime.remoting.channels.tcp;

using remotesample;

namespace

remotesampleserver}}

將其編譯為乙個exe檔案:csc /r:system.runtime.remoting.dll /r:remoteobject.dll remoteserver.cs

3.0客戶端

using system;

using system.runtime.remoting;

using system.runtime.remoting.channels;

using system.runtime.remoting.channels.tcp;

using remotesample;

namespace

remotesampleclient}}

同樣的,將其編譯為exe檔案:csc /r:system.runtime.remoting.dll /r:remoteobject.dll remoteclient.cs

然後先執行remoteserver.exe,再執行remoteclient.exe

輸出:我被構造了!(server端)

3(client端)

假如你身邊有2臺電腦,再試試把其中的"tcp://localhost:6666/remoteobject"改為乙個具體的ip位址,如"tcp:";之後將remoteserver.exe

和remoteobject.dll拷貝後,在一台電腦上執行。再將remoteclient.exe

和remoteobject.dll拷貝後再另一台電腦裡執行。執行的結果和上面一樣。這時我就有疑問了:

1.客戶端獲得的remoteobj,到底是怎麼來的。

2.remoteobj呼叫的方法是誰的?伺服器還是客戶端?

3.這麼做有什麼意義?

先從第1個開始著手。我很好奇這個dll起的作用。為什麼客戶端和伺服器都需要乙份dll?從上面的執行結果來看,server端既然能執行建構函式,那說明物件一定是再server端建立的,只是說客戶端用某種方式獲取了這個物件的引用。這樣的話我就推測問題2一定是呼叫的伺服器端的方法。那麼,客戶端的dll到底有什麼用呢?如果不放這個dll我想連語法都通過不了把,remoteobject

remoteobj = (remoteobject)activator.getobject(typeof(remoteobject), "tcp://localhost:6666/remoteobject");這行裡的remoteobject

肯定就需要dll來宣告。嘿嘿,我就猜想,它絕對只是宣告的作用,為了驗證我對1,2問題的猜想。其中執行server端那台的機子**不變,客戶端的機子中**稍稍改變下,將remotingobject重新按以下**編譯。

namespace

remotesample

public

intsum(int a, int b)}}

然後替換掉客戶端機子上的那個dll,注意此時客戶端和伺服器端的dll不一樣奧。也許你已經看出了貓膩,哈哈,執行下把。

輸出:我被構造了!(server端)

3(client端)

microsoft .net remoting 提供了一種允許物件通過應用程式域與另一物件進行互動的框架。這也正是我們使用remoting的原因。為什麼呢?在windows作業系統中,是將應用程式分離為單獨的程序。這個程序形成了應用程式**和資料周圍的一道邊界。如果不採用程序間通訊(rpc)機制,則在乙個程序中執行的**就不能訪問另一程序。這是一種作業系統對應用程式的保護機制。然而在某些情況下,我們需要跨過應用程式域,與另外的應用程式域進行通訊,即穿越邊界。

在remoting中是通過通道(channel)來實現兩個應用程式域之間物件的通訊的。首先,客戶端通過remoting,訪問通道以獲得服務端物件,再通過**解析為客戶端物件。這就提供一種可能性,即以服務的方式來發布伺服器物件。遠端物件**可以執行在伺服器上(如伺服器啟用的物件和客戶端啟用的物件),然後客戶端再通過remoting連線伺服器,獲得該服務物件並通過序列化在客戶端執行。

在remoting中,對於要傳遞的物件,設計者除了需要了解通道的型別和埠號之外,無需再了解資料報的格式。但必須注意的是,客戶端在獲取伺服器端物件時,並不是獲得實際的服務端物件,而是獲得它的引用。這既保證了客戶端和伺服器端有關物件的鬆散耦合,同時也優化了通訊的效能。

通讀上面的定義,我想很牛逼哄哄的幾個詞會停留在你的腦海,互動式框架、程序間通訊、跨過程式域、通道、**等等。。。。為了了解這些,確實有必要知道些細節定義。

我自己的總結如下:

遠端物件:這個物件就是上面封裝的那個dll。遠端物件就是執行在伺服器上的物件,客戶端不能獲取這個物件,只能獲取這個物件的引用(序列化)或者**。這個物件必須繼承自marshalbyrefobject(允許支援在遠端處理的應用程式中跨應用程式域邊界訪問物件).

通道:主要的有tcp,http。(補加一句:乙個應用程式在關閉時,一定要登出已註冊的通道。否則會報錯「remoting物件已經斷開連線或不在伺服器上」)

啟用方式:啟用方式主要分客戶端啟用和伺服器啟用,我沒用那麼多,我只研究了伺服器端啟用,即singlecall和singleton方式。singlecall方式是客戶端每次例項化乙個物件,比如上面的**,可以在啟動乙個server的時候啟動多個client,此時每次啟動都會有「我被構造了」。而singleton方式則可以簡單的理解為單例模式,所有客戶端獲得都是同乙個物件的引用,上面的**如果改為singleton,則「我被構造了」只會出現一次。

總結起來就是,伺服器先註冊通道,再註冊物件,之後客戶端再註冊通道,而後獲取物件。

看了這麼多的資料,也了解了些remoting,是時候說第3個問題了。還是想不通這又有什麼意義呢?伺服器中有某個方法可供客戶端呼叫,那我還不如兩邊都using一下這個dll,還搞什麼remoting這麼麻煩的幹嘛啊。初看起來確實是這樣的。但是仔細想想,問題出在上面的**太過於簡單了。因為上面的**呼叫的方法都是寫死的,物件就在伺服器停留了一小會呼叫了一下方法就走了,和伺服器其實沒有太大的聯絡。可是別忘了,.net有委託,有事件啊。如果註冊的物件裡面是有事件的,那麼我在客戶端觸發該事件,而伺服器訂閱該事件,那豈不是作用大了去了。這似乎和我的專案需求沾邊了,很高興。。。繼續研究ing,下篇繼續。  

初探Remoting雙向通訊(四)

原 2013年06月26日 11 11 32 喜歡特別冷的冬天下著雪 閱讀數 2632 之前已經從基本原理上實現了remoting的雙向通訊。準備將其移植到我的專案中,不過為了成功移植,我還是需要再把以前的版本稍作修改才能放心的去做。專案中當一台機子中有工作人員進行了預警資訊標記時 在地圖上會有乙個...

JXTA 雙向通訊

jxta 雙向通訊 可以通過 jxtaserversocket jxtasocket和 jxtaserverpipe jxtabidipipe 來實現 其實現的過程非常的類是我們做ftp的時候所採用的serversocket socket機制,也就是服務斷監聽客戶端連線的原理。以jxtaserver...

Thrift 支援雙向通訊

問題 thrift採用了c s模型,不支援雙向通訊 client只能遠端呼叫server端的rpc介面,但client端則沒有rpc供server端呼叫,這意味著,client端能夠主動與server端通訊,但server端不能主動與client端通訊而只能被動地對client端的請求作出應答。這種...