一般情況下我們用Remoting一個通道應該就夠用了,因為程式要麼是用戶端,要麼是伺服器端。但是有時候也會出現一個用戶端需要串連多個伺服器端的情況,或者一個程式既作為伺服器端(針對內網),又作為用戶端(針對外網)。這個時候就需要註冊多個通道了。
根據一般的經驗,用戶端通道和伺服器端通道應該是不衝突的。但實際的情況呢?看一下以下的代碼:
IChannel serverChannel = new TcpServerChannel( 5000 );
ChannelServices.RegisterChannel( serverChannel, true );
IChannel clientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel( clientChannel );
運行後會出現異常“通道 'tcp' 登入。”(RemotingException)
註冊兩個用戶端通道也一樣會出現這個錯誤: IChannel channel1 = new TcpClientChannel();
ChannelServices.RegisterChannel( channel1, true );
IChannel channel2 = new TcpClientChannel();
ChannelServices.RegisterChannel( channel2, true );
開始我懷疑是連接埠衝突,給每個通道分別設定不同的連接埠: Hashtable props1 = new Hashtable();
props1["port"] = 5001;
IChannel channel1 = new TcpClientChannel( props1, new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel1, true );
Hashtable props2 = new Hashtable();
props2["port"] = 5002;
IChannel channel2 = new TcpClientChannel( props2, new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel2, true );
錯誤依舊。想想也是,如果連接埠衝突,應該是這種錯誤:“通常每個通訊端地址(協議/網路地址/連接埠)只允許使用一次。”(SocketException)
再分析一下原來的錯誤:“通道 'tcp' 登入。”。難道是通道的名字衝突?
趕緊把channel的ChannelName列印出來看一下:
Console.WriteLine( "The Default Channel Name is " + (new TcpClientChannel()).ChannelName );
"The Default Channel Name is tcp"...
問題找到。接下來要做的就是在註冊不同通道的時候,顯式指定其通道名稱。ServerChannel和ClientChannel各有不同的方法,以下樣本其一:IChannel channel1 = new TcpClientChannel( "Channel1", new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel1, true );
IChannel channel2 = new TcpClientChannel( "Channel2", new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel2, true );
BTW:因為很少看到網上Remoting的文章提到多通道的註冊,所以把這個貼出來。也許大家註冊通道的時候就指定了名字,這樣就不會有這個問題。 另外,以上均是在.NET 2.0平台上。
MSDN上的相關說明:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconchannels.htm
"通道名稱在應用程式定義域中必須是唯一的。例如,由於預設通道具有名稱,因此,若要在一個應用程式定義域中註冊兩個 HttpChannel 對象,就必須在註冊它們之前更改通道的名稱。"