一般情况下我们用Remoting一个信道应该就够用了,因为程序要么是客户端,要么是服务器端。但是有时候也会出现一个客户端需要连接多个服务器端的情况,或者一个程序既作为服务器端(针对内网),又作为客户端(针对外网)。这个时候就需要注册多个信道了。
最近两天在完成老师布置得分布式数据库任务,用到.Net 的remoting 技术,考虑到老师提出的要求,一台服务器可以与多个客户端进行连接,一台客户端也需要与多个服务器进行连接所以采用多个信道进行通讯。
开始服务器端配置文件如下:
<configuration>
<System.Runtime.Remoting>
<application>
<channels>
<channel type="System.Runtime.Remoting.Channels.Tcp.TcpChannel,System.Runtime.Remoting" port="5555">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
<channel type="System.Runtime.Remoting.Channels.Tcp.TcpChannel,System.Runtime.Remoting" port="6000">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
<service>
<wellknown mode="SingleCall" type="DB.DBService, DBService" objectUri="base" />
</service>
</application>
</System.Runtime.Remoting>
</configuration>
运行时出现异常:
运行后会出现异常“信道 'tcp' 已注册。”(RemotingException)
看到这个情况,开始以为只能注册一个信道,可是经过查阅书籍,发现了一句话服务器可以监听多个通道,于是很容易想到一个问题,是否信道名重复。
于是改了源文件
<configuration>
<System.Runtime.Remoting>
<application>
<channels>
<channel name="channe1" type="System.Runtime.Remoting.Channels.Tcp.TcpChannel,System.Runtime.Remoting" port="5555">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
<channel name="channel2" type="System.Runtime.Remoting.Channels.Tcp.TcpChannel,System.Runtime.Remoting" port="6000">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
<service>
<wellknown mode="SingleCall" type="DB.DBService, DBService" objectUri="base" />
</service>
</application>
</System.Runtime.Remoting>
</configuration>
增加了红色字体部分,编译运行通过。
在用信道通信的时候,需要显示指定信道名称,如果不指定则系统默认名称为TCP,出错。在客户端配置也是一样的
需要添加name属性。
如果用程序控制的话则用以下代码:(以下代码是从网上找的,没有自己实验过)
IChannel channel1 = new TcpClientChannel( "Channel1", new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel1, true );
IChannel channel2 = new TcpClientChannel( "Channel2", new BinaryClientFormatterSinkProvider() );
ChannelServices.RegisterChannel( channel2, true );