首先介绍一下IcePatch2
IcePatch2服务是Ice中用来解决升级文件同步的一个服务。不知道理解的是否有偏差,反正我是这么理解的.IcePatch2能够把服务器上的某一个目录中的内容同步到客户端上来,在实际的开发中可以用来做策略同步下发,升级等操作。
IcePatch2在 bin目录下提供了IcePatch2Calc.exe IcePatch2Server.exe IcePatch2Client.exe 可以用来模拟一个IcePatch2同步下载的一个小型的情景。如果需要进一步编程实现的话,则需要参考Ice的相关文档,一级demo中有一个MFC的IcePatch2的例子。
然后介绍一下IceGrid
IceGrid 我的理解就是所谓的网格计算。在大型的项目中,可以起到服务器资源平衡的作用,不过在我看来,在部署IceGrid的项目中,IceGrid本身也有可能成为服务器性能的一个瓶颈。
别的就不多废话了,关与更多 IceGrid的功能及使用方法请参看Ice使用手册,网上有一个中文版的,但是版本很旧,适合新手看一下,我就看了好几遍,最新的文档要到zeroc去下载,目前好像是3.4。
我现在的项目中服务器用了IceGrid,客户端需要编码实现IcePatch2从服务器上同步一个文件夹,然后问题就来了。
IcePatch2需要指定服务器的Endpoints,这样才可以定位到服务器。
但是IceGrid使用Ice.Default.Locator 这样一个定位器属性来指定 一个定位器,然后由这个定位器来负责定位和启动服务器。
因此在我的程序中,只有Ice.Default.Locator而不存在服务器的Endpoints. 因此通过IcePatch2的代码根本就没有办法定位到服务器,其实IcePatch2给定的代码中压根就没有设置Locator的部分。
为了解决这个问题,我不得不修改了Ice的源码。 Ice提供2个版本的Ice分发包,一个是Source Distributions 这个是有源码的,还有一个是Windows Installers,这个是没有源码的,庆幸的是我下载的是有源码的那个。下面的代码是C:\Ice-3.4.0\cpp\src\IcePatch2Lib\ClientUtil.cpp中IcePatch2用到的一个函数。红色部分是我修改过的,最初始的代码忘记是啥样子的了。
修改之后重新编译了IcePatch2.在客户端就可以只设置Locator而不用去管Endpoints了。
_feedback(feedback),
_dataDir(communicator -> getProperties() -> getPropertyWithDefault( " IcePatch2.Directory " , " . " )),
_thorough(communicator -> getProperties() -> getPropertyAsInt( " IcePatch2.Thorough " ) > 0 ),
_chunkSize(communicator -> getProperties() -> getPropertyAsIntWithDefault( " IcePatch2.ChunkSize " , 100 )),
_remove(communicator -> getProperties() -> getPropertyAsIntWithDefault( " IcePatch2.Remove " , 1 )),
_log( 0 )
{
PropertiesPtr properties = communicator -> getProperties();
const char * endpointsProperty = " IcePatch2.Endpoints " ;
string endpoints = properties -> getProperty(endpointsProperty);
ObjectPrx serverBase;
Identity id;
id.category = properties -> getPropertyWithDefault( " IcePatch2.InstanceName " , " IcePatch2 " );
id.name = " server " ;
if (endpoints.empty())
serverBase = communicator -> stringToProxy( " \ "" + communicator->identityToString(id) + " \ " " );
else
serverBase = communicator -> stringToProxy( " \ "" + communicator->identityToString(id) + " \ " : " + endpoints);
FileServerPrx server = FileServerPrx::checkedCast(serverBase);
if ( ! server)
{
throw " proxy ` " + communicator -> identityToString(id) + ' : ' + endpoints + " ' is not a file server. " ;
}
init(server);
}