蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 597, 评论 - 4064, 引用 - 276

导航

关于

这里是我的技术Blog,下一代CSDN社区Blog在 http://blog.csdn.net/ghj1976/

标签

每月存档

最新留言

  • re:学习笔记:7种结构型设计模式简单对比
    <p>最新在家创业系统 ----刚从国外引进,市场巨大。 ----在家可经营所有国家生意,事业规模宏大。 ----不需求人与说服;不用放厚脸皮去推销。 ----极小投资;零风险;成...
    by jackielongteng(注册) on 2009/6/14 13:43:56
  • re:作用域
    <p>☆                    &deg;∵☆       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
    by jackielongteng(注册) on 2009/6/14 13:03:25
  • re:Html标签嵌套对展示性能的影响
    <p><strong>所有的浏览器都按照你提到的浏览器解析Html规则来解析嘛?</strong></p>
    by Cola(注册) on 2009/6/12 23:07:28
  • re:Html5
    <p>目前来说,HTML5还只是一个梦想,呵呵:)</p>
    by 开心就好(注册) on 2009/6/11 16:31:54
  • re:多线程与SqlConnection.Close
    <p>好服月租型IT服务台,与你共成长! 月租型ITSM软件,注册即可免费体验! 详情请登录官方网站:<a href="http://www.servicezon.co...
    by qzhibo(注册) on 2009/6/3 15:14:21
  • re:多线程Singleton单件模式
    <pre><span style="color: #0000ff;">//Another way public</span> <sp...
    by Yaojian(注册) on 2009/4/22 14:02:35
  • re:Thread.Sleep(0)
    <p>学习了~</p>
    by shuitong888(注册) on 2009/4/8 14:29:24
  • re:Html标签嵌套对展示性能的影响
    <p>DIV固然好 但IE6,7,8 firefox,safari ....做美工的人要累死.</p>
    by ryq1(注册) on 2009/4/3 14:16:25
  • re:用.net 编码实现朗读文本的方法
    <p>我第一次 按键时 能听到声音,但是第二次按键时,没反应。网页一直在 loading.&nbsp;是什么原因?</p>
    by tracytang949(注册) on 2009/3/27 7:01:09
  • re:information_schema.routines与sysobjects
    <p>用sys.procedures多好。</p>
    by luke(注册) on 2009/3/16 16:45:49
  • re:SQL Server 2005 配置发送邮件
    <p>&lt;A href="<a href="http://www.3rt.info">http://www.3rt.info</...
    by ives007(注册) on 2009/2/26 16:47:00
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:45:08
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:32:06
  • re:虚机搭配NLB负载平衡时碰到"没有接口可用于安装新的群集"的解决方案
    <p>google newsid</p>
    by iads(注册) on 2009/2/13 17:25:07
  • re:try catch 与线程
    <p>确实是这样的。因为异常机制本质上是堆栈操作,而各线程的堆栈是独立的。</p>
    by st_szr(注册) on 2009/1/21 9:46:05
  • re:try catch 与线程
    <p>没啥啊,线程就是新启动了一个,当然异常不会影响到原有的线程了。</p> <p>你应该在线程里面合适的位置写上自己的捕获代码就行了。</p>
    by laozizhu(注册) on 2009/1/19 16:33:21
  • re:我的2008,征服天堂
    <p>蝈蝈,可惜我帮不了你啊!</p>
    by laozizhu(注册) on 2009/1/19 16:25:45
  • re:try catch 与线程
    <p>呃&hellip;&hellip;是这样的。可怎么处理呢?</p>
    by Anders Liu(注册) on 2009/1/19 11:58:05
  • re:我的2008,征服天堂
    <p>博主是不是去了师部 做了侦查营长呢?</p>
    by huobazi(注册) on 2009/1/9 14:15:33
  • re:我的2008,征服天堂
    <p>@ghj1976:看来真的危机了</p>
    by 开心就好(注册) on 2009/1/9 10:17:37
  • re: 网络带宽的单位
    不过传输的时候,往往还有压缩。
    by luke(匿名) on 2008/12/15 11:00:21
  • re: 网络带宽的单位
    除10不仅仅是为了方便,在传输中,往往加上控制位,所以一个字节往往需要10Bit.
    by 关门放狗(匿名) on 2008/12/13 16:01:30
  • re: 多缓存并存
    对跨进程甚至跨服务器缓存的性能比较怀疑,进程通信和跨服务器通信代价不菲。即使有已有进程外数据可用,如果考虑在进程做份缓存,定期再进程间同步是否更佳?
    by jinglecat(匿名) on 2008/12/12 18:00:05
  • re: 网络带宽的单位
    好像还有一个为了方便换算,厂家使用的是 除10的处理方式的说法:于是100Mb/sec = 100M / 10 = 10M Byte/sec 所以我通常都是用除10而不是除8来做运算的。
    by kentliu(匿名) on 2008/12/11 11:38:55
  • re: 网络带宽的单位
    又不是大S小s
    by luke(匿名) on 2008/12/10 12:04:50

广告

 

比如我们有下面的需求:

三台电脑: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);

}
}

 

参考资料

 

客户端提示 信道 http 已注册
http://topic.csdn.net/t/20051219/15/4468126.html

如何取消RemotingConfiguration.RegisterActivatedClientType的注册类型
http://topic.csdn.net/t/20050116/16/3729762.html

 

RemotingConfiguration.Configure (String, Boolean) 中隐藏的秘密
http://blog.csdn.net/blue_sky_blue_heart/archive/2006/08/28/1130914.aspx

Remoting给远程对象属性赋值
http://topic.csdn.net/u/20070614/15/1d5a7738-e676-489e-978a-b194579d560b.html

打印 | 张贴于 2008-04-18 15:54:27 | Tag:.net 编程心得  技术随笔  网站开发管理相关内容  .net 3.5  .net 3.0

留言反馈

#re: 如何用.net Remoting实现一个客户端需要连接多个服务器端? 编辑
创建远程对象的一段代码

/*RemotingConfiguration.RegisterActivatedClientType(typeof(Server.File),
"tcp://"+server+":"+port.ToString());
file = new Server.File();*/
string url = "tcp://"+server+":"+port.ToString();
System.Runtime.Remoting.Activation.UrlAttribute urlattr = new System.Runtime.Remoting.Activation.UrlAttribute (url);
object[] args = {urlattr};
file = (Server.File)Activator.CreateInstance(typeof(Server.File),null,args);




2008-04-18 15:56:17 | [博主:ghj1976]
博客主人设置本博客不允许匿名用户发表言论,请登录后再试

Powered by: Joycode.MVC引擎 0.5.1.0