程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Remoting基本原理及擴展機制(中)(2)

Remoting基本原理及擴展機制(中)(2)

編輯:關於C語言

注意它的返回值是IClientChannelSink,而不是IMessageSink,這樣我們就無法將僅實現了IMessageSink接口的CustomMessageSink插入。為此,我們讓CustomMessageSink也實現IClientChannelSink接口,只不過在實現IClIEntChannelSink接口中的方法時,我們全部拋出異常,以表示這些方法不應該被調用到。這樣我們就可以瞞天過海般地利用ChannelSinkProvider創建出一個MessageSink。現在問題來了,這個MessageSink雖然創建出來了,但是它被插入Pipeline了嗎?其實,我們在上一篇文章中就漏過了一個問題——那些利用ChannelSinkProvider創建出來的ChannelSink是如何被插入到Pipeline中的,明白了它的原理,就自然解決了上面的問題。

Pipeline

Pipeline是何物?我們並沒有解釋清楚這個概念,是否存在一個對象它就叫Pipeline或者類似的名字?遺憾地告訴你,沒有!可以說這裡的Pipeline是一個抽象的概念,它表示了當我們調用一個遠程對象時從RealProxy到StackBuildSink之間所經過的一系列Sink的集合,但是並不存在一個單獨的鏈表把這些Sink全部鏈接起來。也就是說並不存在一個大的Sink鏈表,當你觸發遠程方法後,我們就依次從這個鏈表中取出一個個的Sink,大家挨個處理一下消息。不過在遠程對象的代理中倒是維護了一個由ChannelSink組成的鏈表。不過需要注意它並不代表整個Pipeline,而只能算是其中一部分,在後面我們會看到Pipeline中還包括了很多其他類型的Sink。這個鏈表保存在RealProxy的_identity對象中,鏈表是通過IClIEntChannelSink的Next屬性鏈接起來的,在_identity對象中保存鏈表的第一個元素,其他元素可以通過Next屬性獲得,如下圖所示:

下面我們來看看這個鏈表是如何得到的。每當我們通過TransparentProxy調用遠程方法時,如下圖所示,最終會調用到RemotingProxy中的InternalInvoke方法??????????$?????(,它將負責把各個ChannelSink創建出來並鏈接在一起。

1: internal virtual IMessage InternalInvoke(IMethodCallMessage reqMcmMsg,
2: bool useDispatchMessage, int callType)
   3: {
4: //...
5: if (identity.ChannelSink == null)
6: {
7: IMessageSink envoySink = null;
8: IMessageSink channelSink = null;
9: if (!identity.ObjectRef.IsObjRefLite())
10: {
11: RemotingServices.CreateEnvoyAndChannelSinks(null,identity.ObjectRef,
12: out envoySink , out channelSink );
13: }
14: else
15: {
16: RemotingServices.CreateEnvoyAndChannelSinks(identity.ObjURI, null,
17: out envoySink , out channelSink );
18: }
19: RemotingServices.SetEnvoyAndChannelSinks(identity, envoySink,channelSink );
20: if (identity.ChannelSink == null)
21: {
22: throw new RemotingException("..."));
23: }
24: }
25: //...
26: }代碼 3

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved