Remoting的几个疑惑

时间:2021-06-07 00:30:33

写完《关于Remoting》之后,算是把这几天学习Remoting的思路理了一下。Remoting的基本知识是很简单的,但一旦深入,就会发现博大精深。昨天看到微软社区的一贴广告,说*的某个MVP写了一本书,是专门讲IIS的安全知识的。于是想到,如果要把微软产品的每一项功能去穷尽,可能每个看似很小的模块都能写成一本大部头书吧。Remoting也是如此,要把每个细节都弄清楚,谈何容易。

我之学习Remoting是带着目的而来的,起因还是公司要做的项目。最初在WebService和Remoting之间权衡,最后因为项目主要应用在局域网中,而Remoting在局域网内的性能优势是WebService不可比肩的。所以选定了它。Remoting是一个分布式处理服务。我们的想法是要在服务器上部署多个服务,而客户端则接收服务处理具体的业务。在Remoting中,我们可以简单地将它要传送的远程对象看成是一个服务。接收服务,就是实例化这个远程对象,再调用其方法就OK了。

看似简单,但问题也接踵而至。首先,我们在服务器端提供的服务是可以定制的。这里所谓定制,即管理员可以在服务器端关闭或启动指定的服务,同时可以查看其当前状态。也就是说,要提供类似windows操作系统下的“服务”系统。然而这就是问题的关键。Windows服务中,每一项服务就是一个进程,关闭该服务,其实就是关闭其进程。而在Remoting中,我们也可以将其通道看作一个进程,一个通道又占用一个端口。

设想一下,如果我们要提供多个服务,且将一个服务当作一个进程的话,在Remoting中,就将占用多个通道和端口了。产生的问题是:
1、端口占用过多,是否会影响系统的性能?
2、不能只使用80端口。那么如果使用了其他端口,怎样通过防火墙?

如果大家还不太清楚这个问题,可以设想WebService。在WebService中,每提供一个服务,都将在IIS下创建一个虚拟目录来指向它。我仔细看了IIS的SDK,不管是用编程的方式,还是直接在操作系统下操作IIS,都没有关闭一个虚拟目录的功能,除非将其删掉。也就是说,要关闭这个指定的Web服务是不行的。唯一的方法就是关闭其Web站点。默认情况下,你建立了多个Web服务,都会放在默认的web站点下。这样,你关闭了Web站点,事实上就关闭了所有的服务。这与Remoting何其相似!Remoting中,你也能够关闭通道,那么这个通道所承载的所有远程对象(即服务)也就被关闭了。

好,那么我们就退而求其次吧,就用关闭通道的方式来停止服务。我们有两个方案来选择。一是并不关闭通道,而是关闭其对客户端的监听,方法是StopListening()。这样有个好处,就是通道仍然存在,一旦你需要使用,还可以开启通道,方法是StartListening(Remoting中,一旦注册了通道,默认就开启了监听)。第二个方案是注销通道,方法是UnRegisterChannel()。一旦注销了该通道,通道就不能使用了,而通道所占用的端口也将被释放。

这两个方案都很有用。如果我们要暂停服务,可以使用第一种,它便于我们重启。如果要彻底停止服务,可以使用第二种。看来问题以一种妥协的方式解决了!?遗憾的是,我们在做测试的时候,发现这两种关闭通道的方法是由延迟的。当我们在客户端关闭通道后,客户端调用远程对象方法,发现仍然可以正常使用。起初我们怀疑是激活方式的问题。因为我们最初采用的是SingleCall方式,它是无状态的。但改为客户端激活方式,仍然如此。为对象加上生命周期,还是照旧。

那么什么时候它才真正关闭呢?老实说我不知道。在测试时,我们大约过了一分钟,再在客户端调用远程对象方法,这时才出现异常,提示目标不能正常连接。

即时这个方案能实现,仍然不符合我们要求的。我们理想的答案,还是希望能操作每个指定的对象。了解了一些Remoting的知识,发现Remoting的一个通道注册多个远程对象,它的管理方式是把这些远程对象放在一个哈希表中,然后为每个远程对象指定一个唯一标识,作为哈希表的键值。当客户端发出请求后,可以根据这个键值来找到请求的对象,然后实例化它。我们看通道注册对象的方法,RegisterWellknownServiceType(),这个Register大概就是将其添加到这个哈希表中吧。遗憾的是,没有找到对应的UnRegister()方法。因为我们的想法是,如果能够把对象从这个哈希表中移出,客户端发出请求时,自然找不到该对象,此时会抛出异常,不就等同于关闭了该服务吗?没有UnRegister()方法,我也没有能找到得到这个哈希表的方法,那么这个Idea也只能夭折了。真是不甘心啊!

总结我的疑惑就是:

1、怎样将已注册的对象从通道中注销(或移出)?

2、退而求其次的方案,那么为什么关闭了监听或关闭了通道,会有一个时间上的延迟?延迟又是多少?