三 ICE开发初级研究

http://www.acejoy.com/bbs/viewthread.php?tid=2878&extra=page%3D1ICE开发初级研究(一)最近一段一直在忙于工作,事情比较多,除了偶尔在这里看看帖子,一直没有写什么东西。再加上忙于PurenessScopeSerever0.72版本的开发,争取0.72版再次给大家带来一些提升。其实想想,技术这种东西,并非一定要高深到谁也看不懂才叫牛。技术这样的东西,分享是很关键的。只有简单好用的技术,才会获得大规模的应用。ICE这个东西,说实话以前我比较惧怕。到处看到的文章都是说,重量级的中间件,虽说是源于Corba,但是复杂度感觉不低于ACE。网上搜索ICE也都是比较基础的应用。最近工作用到了,想跟着工作的进度,陆续写一些ICE有关的实际应用。供大家参考和使用,抛砖引玉。这里特别感谢True的大力支持。现在看来,ICE还是不用惧怕的,ACE都能活下来,再看ICE实际变的简单了,呵呵。里面难免有些偏颇之处,请大家指正。废话少说,要用ICE,需要先去官网下载一个ICE的开发库。ICE的开发官网是http://www.zeroc.com,目前最新版本是3.4.1。下载地址为:http://www.zeroc.com/download.html 这里我吃了一个亏(我在windows下使用,linux下倒是少了这些麻烦),因为没注意版本,我本人用的是VS2005,结果后来编码完后,运行竟然到处报错。后来才知道ICE的3.4.1只支持VS2008 SP1以后的开发环境(感觉怎么ICE的开发者就不能像ACE的开发者那样,支持多版本的编译器呢?),如果你是VS2005环境的话,建议下载3.3.1,如果是2008,建议下载3.4.0,如果是2008 SP1之后的版本,建议使用3.4.1。如果是windows推荐下载msi版本,linux的话下载rpm,安装都比较省事,一路下一步就行了。安装后打开环境变量,按照ACE的推荐那样设置一下你的ICE路径然后打开你的VS2005,先建立一个服务器端(win32控制台程序)。(我的环境变量叫做ICE_ROOT)然后在打开工程属性,里面添加C++附加路径($(ICE_ROOT\include))和你的lib附加路径($(ICE_ROOT)\lib),然后添加需要用到的iced.lib iceutild.lib行了,这个工程就可以写ICE的程序了。ICE使用前需要定义一个接口文件。一般是.ice命名的(是你起的名字,比如我的例子是TestICE.ice)#ifndef _TESTICE_H#define _TESTICE_Hmodule Test{interface TestICE{int ping();int GetTime(out string strTime);};};#endif这里是一个接口文件,我来给大家一行行解释。(其实大部分写法都是固定的)首先,你必须定义你的接口的一个NameSpace的名字。这里比如module Test意思就是你声明了一个叫做Test的命名空间,这个是很重要的,因为未来在你的代码中,要写上using namespace Test。下面是interface TestICE这里是你声明的接口名称。这个就像把很多网线捆起来的束,在访问的时候,要先找到束,再找里面对应的接口。这样做,很方便管理你的接口,比如你可以定义一个DB接口集合,一个Logic接口集合。。。。层次感会跟清晰。我在我的TestICE里面,定义了两个函数。int ping();int GetTime(out string strTime);这里,我这两个函数都没有具体实现,呵呵,只是为了测试而已。然后,这个文件写好了,进入你的ICE的安装路径,进入bin目录,然后cmd进入这个目录。在命令行敲入slice2cpp TestICE.ice 这里要说明一下,如果你使用的是路径,比如slice2cpp d:\TestICE.ice 这样是可以的,但是如果路径中有中文,会报错。如果一切顺利,你将会在你的*.ice路径下得到两个文件,一个.h一个.cpp。其实感觉,如果你能仔细分析懂这些代码,弄个模板自己改一个也行,不需要ICE帮你生成,当然,简单起见,还是ICE的工具比较方便,毕竟可以帮你检查语法。有了这两个文件,直接拷贝到你的Server和Client工程中,这两个都需要用。然后写一个类,继承这个接口的虚类。
#include"Ice/Ice.h"
#include"TestICE.h"

#include
<string>

usingnamespacestd;

usingnamespaceTest;

classCTest :publicTestICE

{

public:

intping(constIce::Current&);

intGetTime(string&strTime,constIce::Current&);

};

这样,一个ICE的接口对象,就和你的实际方法绑定成功了。实现么,呵呵,你可以自己去写啦。然后先看看服务器的源码。classCMainServer :publicIce::Application

{

public:

virtualintrun(int,char[]);

};



intCMainServer::run(intargc,char
argv[])

{

try

{

Ice::ObjectAdapterPtr AdaptrPtr
=communicator()->createObjectAdapter("SampleTest");

Ice::ObjectPtr Object
=newCTest;

AdaptrPtr
->add(Object, communicator()->stringToIdentity("SampleTest"));

AdaptrPtr
->activate();

communicator()
->waitForShutdown();

returnEXIT_SUCCESS;

}

catch(constIce::Exception ex)

{

printf(
"[Main]Error = %s.\n", ex);

return-1;

}

}



intmain(intargc,char*argv[])

{

CMainServer app;

app.main(argc, argv,
"init.config");

getchar();

return0;

}


这里的代码其实挺简单的,代码基本是固定的。你需要的是修改CMainServer::init()方法,和在你的服务器exe路径下,添加一个init.config的文件。这是一个配置文件,你可以把你的一些ICE配置参数写入这个文件。init.config里面的内容是(这是服务器的配置文件,客户端不是这个)SampleTest.Endpoints=tcp -p 10000这句话的意思是,你在本机开启一个服务,IP默认是你的服务器IP,端口是10000下面说一下init()里面在干什么Ice::ObjectAdapterPtr AdaptrPtr = communicator()->createObjectAdapter("SampleTest");创建了一个对象代理。命名为SampleTest,这个名字你可以随便起。(communicator()实际是一个ICE的智能指针)Ice::ObjectPtr Object = new CTest;你创建一个ICE指针对象,指向你的类。AdaptrPtr->add(Object, communicator()->stringToIdentity("SampleTest"));这句话是,将你的类指针,注册到你的AdaptrPtr对象中,并关联你的"SampleTest"。内部生成一个唯一访问码和你的类指针关联。如果你有多个类,可以这样一个个指定。AdaptrPtr->activate();communicator()->waitForShutdown();return EXIT_SUCCESS;这三句是固定的,激活你的AdaptrPtr对象,并启动ICE服务。实际上,communicator()->waitForShutdown();会接管你的主线程。好了,就这么多代码,启动你的服务器吧,如果正常,服务器会启动并占据你的10000端口。客户端其实也很简单。客户端的init.config文件是:SampleTest.Proxy=SampleTest:tcp -p 10000如果你要指定你的服务器IP,你可以SampleTest.Proxy=SampleTest:tcp -h XXX.XXX.XXX.XXX -p 10000如果你有多个服务器IP地址(分布网格)SampleTest.Proxy=SampleTest:tcp -h XXX.XXX.XXX.XXX -p 10000-h XXX.XXX.XXX.XXX -p 10000-h XXX.XXX.XXX.XXX -p 10000客户端代码也不复杂。classCMainClient :publicIce::Application

{

public:

virtualintrun(int,char[]);

};



intCMainClient::run(intargc,char
argv[])

{

try

{

stringstrData="I'm a freeeyes.";

TestICEPrx testice
=TestICEPrx::checkedCast(communicator()->propertyToProxy("SampleTest.Proxy")->ice_twoway()->ice_timeout(-1)->ice_secure(false));



if(!testice)

{

printf(
"[CMainClient::run]testice is error.\n");

returnEXIT_FAILURE;

}



intnData=testice->GetTime(strData);

printf(
"[CMainClient::run]GetTime is %d.\n", nData);



returnEXIT_SUCCESS;

}

catch(constIce::Exception ex)

{

printf(
"[Main]Error = %s.\n", ex.what());

return-1;

}

}



intmain(intargc,char*argv[])

{

CMainClient app;

app.main(argc, argv,
"init.config");

getchar();

return0;

}

这里面大部分代码都是固定的,依然只是Init里面,需要修改一下。TestICEPrx testice = TestICEPrx::checkedCast(communicator()->propertyToProxy("SampleTest.Proxy")->ice_twoway()->ice_timeout(-1)->ice_secure(false));这句的代码意思是,你声明一个TestICEPrx接口类,负责从你的init.config文件中获取你的配置参数,去寻找SampleTest对应的接口对象。if(!testice){printf("[CMainClient::run]testice is error.\n");return EXIT_FAILURE;}int nData = testice->GetTime(strData);printf("[CMainClient::run]GetTime is %d.\n", nData);这句代码是,如果你正确的获得了这个对象,你就可以使用这个接口里面的内容了,具体调用方法如上。其实,基础的ICE还是很简单的,随着我自己的研究深入,希望写出更多体会,呵呵。代码在ICE3.3.1和VS2005下测试通过。原文链接: https://www.cnblogs.com/zkliuym/archive/2010/12/17/1909205.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/18920

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午7:51
下一篇 2023年2月7日 下午7:51

相关推荐