初探Remoting雙向通訊(四)

2022-02-03 09:54:06 字數 1648 閱讀 9248

2023年06月26日 11:11:32

喜歡特別冷的冬天下著雪

閱讀數 2632

之前已經從基本原理上實現了remoting的雙向通訊。準備將其移植到我的專案中,不過為了成功移植,我還是需要再把以前的版本稍作修改才能放心的去做。專案中當一台機子中有工作人員進行了預警資訊標記時(在地圖上會有乙個標誌),其他機子需要同步更新。這就是說任何乙個客戶端進行標記時需要通知伺服器,然後讓伺服器去廣播標記。這乙個小動作就需要雙向通訊一次。按照專案需求,我再次修改版本,這次只需要改乙個函式:

修改伺服器訂閱事件函式如下:

void

marshal_obj_subscribeatserver(string msg)

));th.start();

}

然後開啟乙個伺服器3個客戶端,讓其中乙個客戶端發起標記事件,效果如下:

有了這個,我更加肯定的去修改自己的專案了。經過一整天的大改,我把專案除錯通了,開了1個伺服器,2個客戶端,分別設定了斷點,雖然其中事件訂閱處有很多邏輯處理,並不像上面demo那樣只傳送一段文字,但是每乙個斷點都可以執行到,那就說明整體上是通了。刪除斷點後,很高興的看一下新的效果時,卻讓我大失所望:

當乙個客戶端進行標記時,第二個客戶端確實也收到了資訊,但是第乙個客戶端介面已經卡死,很久才能恢復,甚至當機。這就讓我想起了上面這個demo執行的效果時的現象了。上面的三個客戶端收到資訊並不是同時的,而是依次的。況且,所謂的廣播傳送,其實利用的就是多播委託,並不像socket那樣是3個tcpclient來進行通訊的。伺服器端利用marshal得到的物件和3個客戶端啟用得到的物件是同乙個引用(singleton方式),所以客戶端訂閱的事件都是在伺服器同乙個物件上的委託列表裡。當直接呼叫委託的時候,呼叫的是委託的invoke方法,該方法會在執行的時候阻塞當前執行緒,直到委託列表執行完才會將控制權轉回來。這樣一來,委託的超時必然會引起介面的假死(當有更多邏輯處理在事件訂閱函式裡時更糟糕)。呢有什麼辦法呢,查詢了資料,看了"張子陽"的委託與事件覺得很不錯,仔細拜讀了好幾遍。原來委託執行的列表是可以獲取的,而且可以認為的去遍歷,這麼一來就可以解決許多問題:比如有乙個客戶端發生了異常,為了不影響其他的客戶端,可以遍歷的時候try/catch掉;再比如遍歷的時候為了不阻塞客戶端執行緒,可以每次另起乙個執行緒(這裡就用到了begininvoke,它就相當於另起執行緒執行委託,只不過它用的是執行緒池)。好了,再次修改以下伺服器的訂閱函式,如下:

void

marshal_obj_subscribeatserver(string msg)

}

其中getservereventlist()這個方法是在遠端物件裡新加的:

//獲取委託列表

public delegate getservereventlist()

這次,我開了很多客戶端,接收到資訊幾乎是同步的(至少肉眼分辨不出來),並且將專案也進行了改進,也有了重大突破。感謝網上許多樂於分享的大牛們,remoting的學習暫時告一段落,還有其他事情要做,前方的路已然坎坷,而我卻樂此不疲。。。。。

初探remoting雙向通訊(一)

原 2013年06月24日 15 47 07 喜歡特別冷的冬天下著雪 閱讀數 4389 一 從乙個小例子開始 1.0定義物件 namespace remotesample public int sum int a,int b 將其編譯為乙個lib檔案 csc t library remoteobje...

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端的請求作出應答。這種...