逸天阁

击长空、博千里,笑慑鬼魅,坦荡万象。四海皆是可有作为,宇内必有余之归宿。

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  28 随笔 :: 0 文章 :: 189 评论 :: 5 引用
  一般情况下我们用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 对象,就必须在注册它们之前更改信道的名称。"
posted on 2005-11-30 23:19 逸天 阅读(3317) 评论(14)  编辑 收藏 网摘 所属分类: 技术

评论

#1楼 2005-12-01 08:28 瑞雪年      
请教一个问题,RemotingConfiguration.RegisterWellKnownServiceType有选择channel的能力吗?
我想在一个应用程序域中创建两种不同的TCP或HTTP信道,如:一个Remoting服务用压缩的方式,而另一个不用。可以吗??
http://zhongzf.cnblogs.com/archive/2005/08/10/211252.html">http://zhongzf.cnblogs.com/archive/2005/08/10/211252.html

  回复  引用  查看    

#2楼 2005-12-01 08:56 Terrylee      
如果用配置文件去注册多通道该如何解决呢?
  回复  引用  查看    

#3楼[楼主] 2005-12-01 13:23 逸天      
MSDN上的相关说明,得好好看看.NET自带的帮助了 -_-! :
  "信道名称在应用程序域中必须是唯一的。例如,由于默认信道具有名称,因此,若要在一个应用程序域中注册两个 HttpChannel 对象,就必须在注册它们之前更改信道的名称。"

  另外,由于 TcpChannel 和 HttpChannel 默认的信道名称不一样(分别是"tcp"和"http"),所以如果这两种类型的信道只注册一次的话,可以用默认构造函数。
TcpChannel chan1 = new TcpChannel(8085);
HttpChannel chan2 = new HttpChannel(8086);
ChannelServices.RegisterChannel(chan1);
ChannelServices.RegisterChannel(chan2);

  回复  引用  查看    

#4楼[楼主] 2005-12-01 14:07 逸天      
TO : Terrylee
Remoting配置是支持多信道注册的,以下是示例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel name="Channel1" port="8086" ref="tcp"/>
<channel name="Channel2" port="8088" ref="tcp"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>

  回复  引用  查看    

#5楼 2005-12-01 14:24 wu ming      
如果接着有一个远程对象要建立,我如何控制它放到指定的渠道呢?

alex
http://www.cnblogs.com/QPG2006

  回复  引用  查看    

#6楼[楼主] 2005-12-01 20:37 逸天      
@瑞雪年, wu ming :

  就我所知,目前在Server端似乎还没有办法为WellknownServiceObject选择其使用的信道。.NET Remoting的通信信道的选择,好像是由底层自己进行的。而且Server端注册的ObjectUri,只是一个不完整路径,例如"Test",而在Client端使用的时候,则是完整Url路径:tcp://localhost:8086/Test。
 
  我所测试的代码里,通过Client激活对象时所指定的URL,可以选择远程通信所用的信道的类型。这主要通过其协议"tcp://"和端口"8086"来确定。
 
  也就是说,以下例子中,我们在服务器端注册的TestClass对象,无法确定其在tcp信道上还是在http信道上。一切都是根据客户端的具体请求来选择。

共享测试类如下:
namespace Share
{
    public class TestClass : MarshalByRefObject
    {
        public string Hello()
        {
            return "Hello from remoting!";
        }
    }
}

Server端使用这个配置文件,分别注册了一个tcp信道,一个http信道。远程对象只注册了一个用于测试的类。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel name="Channel1" port="8086" ref="tcp"/>
        <channel name="Channel2" port="8088" ref="http"/>
      </channels>
      <service>
        <wellknown mode="Singleton" type="Share.TestClass, Share" objectUri="Test"/>
      </service>
    </application>
  </system.runtime.remoting>
</configuration>

Server 代码:
RemotingConfiguration.Configure( "Server.exe.Config" );

Client端也注册了两个信道,tcp的和http的,配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel name="Channel1" port="8186" ref="tcp"/>
        <channel name="Channel2" port="8188" ref="http"/>
      </channels>
    </application>
  </system.runtime.remoting>
</configuration>
 
Client代码:
RemotingConfiguration.Configure( "Client.exe.Config" );
Share.TestClass test1 = (Share.TestClass) Activator.GetObject(
    typeof( Share.TestClass ), "tcp://localhost:8086/Test" );
Share.TestClass test2 = (Share.TestClass) Activator.GetObject(
    typeof( Share.TestClass ), "http://localhost:8088/Test">http://localhost:8088/Test" );
Console.WriteLine( test1.Hello() );
Console.WriteLine( test2.Hello() );

  回复  引用  查看    

#7楼 2005-12-02 08:18 瑞雪年      
-> 逸天
我也是没找到办法,所以问一下,非常感谢!!!

  回复  引用  查看    

#8楼 2006-03-09 11:14 jasonsc[未注册用户]
我打算在一台机器上运行2个进程:A进程注册一个9090的IpcServerChannel和一个希望连接到9091的IpcClientChannel;B进程注册一个9091的IpcServerChannel和一个希望连接到9090的IpcClientChannel。两个进程具有相同的RemoteObject用来调用。这样是否可行?IpcClientChannel如何指定到具体的RemoteObject?我遇到的问题是A总是会掉用到自己9090上的RemoteObject。谢谢!
  回复  引用    

#9楼 2006-10-28 16:39 BBQB[未注册用户]
使用信道是没有用的,注册了信道后,如果在一段时间没使用就关闭连接,)即是没用了)
  回复  引用    

#10楼 2006-10-28 16:53 BBQB[未注册用户]
使用信道是没有用的,注册了信道后,如果在一段时间没使用就会自动关闭连接,即是没用了
  回复  引用    

#11楼 2007-01-24 14:33 小郑[未注册用户]
web项目上面使用remoting技术出现如下错误:
远程处理配置失败,异常为“System.Runtime.Remoting.RemotingException: 信道“tcp”已注册。
是什么原因阿!?

  回复  引用    

#12楼 2007-03-12 10:42 Kriss[未注册用户]
◎小郑
你要确保信道只被注册一次

  回复  引用    

#13楼 2008-02-25 09:11 RongCha[未注册用户]
用了,行!!
  回复  引用    

#14楼 2008-05-03 12:20 留恋星空      
mark
  回复  引用  查看    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 288177




相关文章:

相关链接: