ServantLocator定位的目标是Servant,而Locator定位的目标是“Ice Object”,即一个可定位的“Ice Object”代理。Servant是::Ice::Object的继承树的子类,是我们接口定义的实现体,充当的是"Ice Object"某面(facet)的Servant。
ServantLocator的同一级物品是ASM(active servant map),是一次远程调用的服务端ObjectAdapter在分派调用而要适配Servant时使用到的。
而Locator,则是Object和ObjectAdapter的名字服务。Locator本身是一个Object Servant,以Ice Object的方式提供服务。Locator本身存储着ObjectProxy以及ObjectAdapter的物理位置,以代理的方式提供名字服务给(一次)远程调用的客户端使用。有这样一种情况,你并不知道提供目标Object的ObjectAdapter物理地址而只知道它的名字,但有一个Locator知道这个名字的对应的ObjectAdapter的真实地址,我们就可以通过这个Locator的代理查询出ObjectAdapter真实的地址。我们通常在创建代理时,指定终为"ObjectName:tcp -h xxx.xxx.xxx.xxx -p yyyy",其实":"后面的地址是ObjectAdapter的直接地址。而我们要使用Locator时,指定终端为"ObjectName@ObjectAdapterName"。当我们第一次调用创建出的代理时,Ice环境会调用Locator代理查询出真实的网络终端地址,然后才进行通讯。参考ObjectAdapter如何createProxy可知道,"ObjectName:tcp -h xxx.xxx.xxx.xxx -p yyyy"为直接代理(即newDirectProxy),而"ObjectName@ObjectAdapterName"为间接代理(即newIndirectProxy)。
ObjectAdapter分别提供了两个接口函数,addServantLocator(const ServantLocatorPtr& locator, const string& prefix)以及setLocator(const LocatorPrxPtr& locator)。虽然大家都叫locator,但作用是完全不同的。首先ServantLocator是LocalObject不进行远程调用,而Locator是代理,也就是它必须被远程调用查询。ObjectAdapter在active时就会调用Locator代理,将自己注册上去,让其它使用Locator查询服务的代理方可以查询到它。利用一个direct proxy来指明它的监听地址。也就是返回这个dummy代理,让你创建代理后复制dummy代理的endpoints。
Locator还有另一作用,就是指明ObjectAdapter,返回一个指定了ObjectAdapter的Ice Object的代理给你。和查询ObjectAdapter一样,同样返回一个直接指定了ObjectAdapter地址的代理给你。而你连ObjectAdapter的名字也不用指明。
What is ServantLocator?
What is Locator?