比如我们有下面的需求:
三台电脑:A,B,C。
我们在 B 和 C 上部署了同样的一个服务,电脑 A 需要根据客户端的选择,自动的切换到底是调用B的服务,还是C的服务。
要实现这个需求,核心就在客户端的调用上。下面我们用一个简单的演示这个功能的代码来说明如何实现。
首先:服务器段
服务器段逻辑,这是非常简单的,我们按照之前的.net编写规范,编写代码即可。熟悉.net Remoting 的完全可以跳过这部分。
下面是一段简单的服务器段逻辑代码
using System;using System.Collections.Generic;using System.Text;using System.Net;namespace MyServiceComponent{
public class MyComponent : MarshalByRefObject
{
public string GetString(short s)
{
// 返回信息中包含服务器IP,这样我们就知道客户端调用的是哪个服务器
if (s <= 10)
return string.Format("<=10 {0}", GetIP());
else
return string.Format("大于10 {0}", GetIP());
}
protected string GetIP()
//获取本地IP
{
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
return ipAddr.ToString();
}
}
}服务器段的配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="Singleton" type="MyServiceComponent.MyComponent,MyServiceComponent" objectUri="HongjunguoRemotingService" />
</service>
<channels>
<!-- 这里的配置方法,请参看MSDN中 远程处理安全通道技术示例 -->
<channel ref="tcp" port="8088" secure="true" impersonate="true"protectionLevel="EncryptAndSign" />
<serverProviders>
<formatter href="binary" typeFilterLevel="Full"/>
</serverProviders>
</channels>
</application>
<!-- 只有把 customErrors 配置成 Off ,服务器端的详细错误异常,才能传递到客户端默认是不传递完整的错误异常的。 -->
<customErrors mode ="Off" />
</system.runtime.remoting>
</configuration>服务器段调用代码
RemotingConfiguration.Configure( AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false);
客户端
客户端如果我们用以前常用的,把所有客户端的调用信息都写在一个配置文件中,期望简单的用下面代码就不可以了。
RemotingConfiguration.Configure(configFile, true);如果我们用上面的方法时,则会收到下面的异常:
远程处理配置失败,异常为“System.Runtime.Remoting.RemotingException:
试图重定向类型“MyServiceComponent.MyComponent, MyServiceComponent”的激活,而该类型已被重定向。
在 System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo.AddWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfigHandler.RegisterWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo.StoreRemoteAppEntries(RemotingXmlConfigFileData configData)
在 System.Runtime.Remoting.RemotingConfigHandler.ConfigureRemoting(RemotingXmlConfigFileData configData, Boolean ensureSecurity)”。
参考我在论坛咨询的帖子
远程处理配置失败,异常为“RemotingException: 试图重定向类型“MySC.MyComponent, MyServiceComponent”的激活,而该类型已被重定向
http://topic.csdn.net/u/20080418/10/a9b02fa0-a230-4fb6-abeb-b7407a6729c1.html
使用.net Remoting 客户端调用服务器段时,需要考虑两个东西:
1、信道的问题(Channel)
2、如何创建远程对象,也就是注册类型
先说信道的问题:
上面例子中, B 和 C 服务器,他们完全可能一个开放的是 TCP 信道,一个开放的是 HTTP 信道。 同时,访问他们服务时,身份验证完全可能是不同的。各自服务器自身的验证。
这就有一个需要解决的问题,如何实现客户端多信道。下面这篇博客对此有比较详细的介绍:
Remoting多个信道(Chennel)的注册问题
http://www.cnblogs.com/kriss/archive/2005/11/30/288177.html
创建远程对象的问题:
如果我们把需要创建的信息写在配置文件中,用 RemotingConfiguration.Configure(configFile, true); 来创建远程对象,就会出现下面的错误。
远程处理配置失败,异常为“System.Runtime.Remoting.RemotingException:
试图重定向类型“MyServiceComponent.MyComponent, MyServiceComponent”的激活,而该类型已被重定向。
在 System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo.AddWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfigHandler.RegisterWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownClientType(WellKnownClientTypeEntry entry)
在 System.Runtime.Remoting.RemotingConfigHandler.RemotingConfigInfo.StoreRemoteAppEntries(RemotingXmlConfigFileData configData)
在 System.Runtime.Remoting.RemotingConfigHandler.ConfigureRemoting (RemotingXmlConfigFileData configData, Boolean ensureSecurity)”。
解决方法,就是下面的演示代码,不写在配置文件中,改自己手工创建,如下面客户端演示代码。
编码创建对象可以使用 Activator.GetObject 或者 Activator.CreateInstance 。
下面就是我的演示代码
针对B服务器的配置文件(主要是通道的配置,注意这两个配置文件验证信息不一样)
注意,这个配置文件中我们可没有下面这样的信息:
<client displayName="client01" >
<wellknown displayName ="Wellknown1" type="MyServiceComponent.MyComponent,MyServiceComponent" url="tcp://192.168.5.2:8088/HongjunguoRemotingService" />
</client>
s1.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<!-- 这里的配置方法,请参看MSDN中 远程处理安全通道技术示例这个技术请参看: http://www.cnblogs.com/zhengyun_ustc/archive/2006/06/09/remoting_InvalidCredentialException.html http://forums.asp.net/thread/1626741.aspx -->
<channel name="Channel1" ref="tcp" port="8081" secure="true" tokenImpersonationLevel="impersonation" protectionLevel="EncryptAndSign" username="ghj1976" password="*****" domain="*****" />
<clientProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</clientProviders>
</channels>
</application>
<customErrors mode ="Off" />
</system.runtime.remoting></configuration>
针对C服务器的配置文件(主要是通道的配置,注意这两个配置文件验证信息不一样)
s2.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel name="Channel2" ref="tcp" port="8082" secure="true" tokenImpersonationLevel="impersonation" protectionLevel="EncryptAndSign" username="communityserver" password="****" domain="***"/>
<clientProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</clientProviders>
</channels>
</application>
<customErrors mode ="Off" />
</system.runtime.remoting></configuration>
客户端程序的调用代码
public partial class ClientForm : Form
{
public ClientForm()
{
InitializeComponent();
}
private Dictionary<string, MyServiceComponent.MyComponent> dict =
new Dictionary<string, MyServiceComponent.MyComponent>(2);
private void button1_Click(object sender, EventArgs e)
{
short ss = 0;
if (!short.TryParse(this.textBox1.Text, out ss))
return;
string key = string.Empty;
string url = string.Empty;
if (radioButton1.Checked)
{
key = "s1.config";
url = "tcp://192.168.5.2:8088/HongjunguoRemotingService";
}
else if (radioButton2.Checked)
{
key = "s2.config";
url = "tcp://192.168.5.7:8088/HongjunguoRemotingService";
}
else
return;
MyServiceComponent.MyComponent com = null;
if (!dict.TryGetValue(key, out com))
{
string configFile = Path.Combine(
Path.GetDirectoryName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile), key);
RemotingConfiguration.Configure(configFile, true);
//com = new MyServiceComponent.MyComponent();
com = (MyServiceComponent.MyComponent)Activator.GetObject(
typeof(MyServiceComponent.MyComponent), url);
dict.Add(key, com);
}
else
{
if (com == null) return;
}
string www = com.GetString(ss);
MessageBox.Show(www);
}
}
如何用.net Remoting实现一个客户端需要连接多个服务器端?
来源:博客 作者:不详 时间:2008-04-22 点击:160 次
相关文章:
文章搜索
推荐文章
推荐产品
|
VARCHART XGantt
全球知名的甘特图控件,能够实现如 Microsoft Project 般强大的项目管理功能。
|
|
TurboDemo 中文版
TurboDemo - 抓取屏幕截图并通过动态演示示例及手册解释软件、个人电脑应用程序、网站与产品。
|
|
BCGControlBar Library .NET Edition
该组件包含大量可自定义程度高、可设计性好的组件,使用户可创建精致美观的图形用户界面。
|
|
WebUI Studio.NET
WebUI Studio.NET 是一套用于开发专业 ASP.NET web 应用程序必不可少的控件。
|





