公司里越来越多的接口以ICE方式提供了,以前没接触过,所以我这两天也抽了点时间研究了下ICE,参考了网上很多帖子,才终于跑通第一个简单的ICE
接下来贴上我所有环境的搭建过程以及代码,和大家分享下ICE所带来的快乐
ICE是什么我就不多说了
1、 一款高性能的中间件,基于ICE可以实现电信级的解决方案。
2、Ice 应用适合于异构平台环境中使用:客户和服务器可以采用不同的编程语言,可以运行在不同的操作系统和机器架构上
3、目前支持C++,JAVA,C#,VB,Python,Ruby,PHP等多种语言,多种语言之间采用共同的Slice(Specification Language for Ice)进行沟通。
想知道更多请去http://www.zeroc.com/
我这里用了两台机器,一台是linux rdhl5 一台是xp 在linux上跑一个C++服务端程序和一个C++客户端程序,xp上跑一个ruby客户端程序
首先开始搭建环境……
1、linux上ICE环境
由于我的机器是rdhl5,我去官网上下的Ice-3.3.1-rhel5-i386-rpm.tar.gz
http://www.zeroc.com/download/Ice/3.3/Ice-3.3.1-rhel5-i386-rpm.tar.gz
解开之后包含以下文件
[root@localhost tmp]# tar -zxvf Ice-3.3.1-rhel5-i386-rpm.tar.gz
db46-4.6.21-3ice.rhel5.i386.rpm
db46-devel-4.6.21-3ice.rhel5.i386.rpm
db46-java-4.6.21-3ice.rhel5.i386.rpm
db46-utils-4.6.21-3ice.rhel5.i386.rpm
ice-3.3.1-1.rhel5.noarch.rpm
ice-c++-devel-3.3.1-1.rhel5.i386.rpm
ice-java-3.3.1-1.rhel5.noarch.rpm
ice-java-devel-3.3.1-1.rhel5.i386.rpm
ice-libs-3.3.1-1.rhel5.i386.rpm
ice-php-3.3.1-1.rhel5.i386.rpm
ice-python-3.3.1-1.rhel5.i386.rpm
ice-python-devel-3.3.1-1.rhel5.i386.rpm
ice-ruby-3.3.1-1.rhel5.i386.rpm
ice-ruby-devel-3.3.1-1.rhel5.i386.rpm
ice-servers-3.3.1-1.rhel5.i386.rpm
ice-utils-3.3.1-1.rhel5.i386.rpm
mcpp-devel-2.7.2-1ice.rhel5.i386.rpm
特定语言的包你可以选择性安装
比如我这里服务端就跑C++ 所以这几个包我就可以不用装了
db46-java-4.6.21-3ice.rhel5.i386.rpm
ice-java-3.3.1-1.rhel5.noarch.rpm
ice-java-devel-3.3.1-1.rhel5.i386.rpm
ice-php-3.3.1-1.rhel5.i386.rpm
ice-python-3.3.1-1.rhel5.i386.rpm
ice-python-devel-3.3.1-1.rhel5.i386.rpm
ice-ruby-3.3.1-1.rhel5.i386.rpm
ice-ruby-devel-3.3.1-1.rhel5.i386.rpm
其他的几个包就都用RPM -ivh 安装吧 ,安装时候注意包之间的依赖关系,得按照顺序安装。默认会安装到/usr/ 目录下,执行文件在/usr/bin目录下 include lib分别在/usr/include 和 /usr/lib 这里不用我多说…… 执行下 slice2cpp 提示no input file 就证明ICE环境已经可以工作啦
下面我们来搭建服务端
1、先新建个ice文件 demo.ice
2、执行 slice2cpp demo.ice 执行成功后可以看到当前目录下生成了demo.cpp 和demo.h两个文件
3、新建Server.cpp
4、编译Server.cpp
执行g++ -I. -I/usr/include -o server demo.cpp Server.cpp
-L/usr/lib -lIce -lIceUtil
接下来我们弄和服务端跑在一台机器上的c++客户端
1、新建Client.cpp
2、编译Client.cpp
执行g++ -I. -I/usr/include -o client demo.cpp Client.cpp -L/usr/lib -lIce -lIceUtil
好了 现在我们先执行下./server 然后再在另一个终端执行./client
每执行一次./client server端就会打印出Its just a test!from cpp ice client
再接下来我们来搞xp下ruby调用服务端ice接口
首先xp下安装ruby我就不用说了
下载one-click installer 安装 http://rubyforge.org/frs/download.php/47082/ruby186-27_rc2.exe
xp下搭建ice环境
下载支持ruby的版本 Ice-3.3.1-VC60.msi
http://www.zeroc.com/download/Ice/3.3/Ice-3.3.1-VC60.msi
安装完成之后做两件事情
1、set PATH=<Ice installation root directory>\bin;%PATH%
2、set RUBYLIB=<Ice installation root directory>\ruby;%RUBYLIB%
完成之后cmd下运行下slice2rb 发现有提示了
ruby运行一下 require'Ice' 没有报错 证明你xp下环境ok了
接下来是ruby调用服务端ice接口客户端实现
1、拿到上面服务端的demo.ice 我保存在E:\workspace\rubyforjason\Ice\目录下面 cmd运行下 slice2rb --output-dir E:\workspace\rubyforjason\Ice\ E:\workspace\rubyforjason\Ice\demo.ice
可以看到E:\workspace\rubyforjason\Ice\ 目录下生成了demo.rb这个文件
2、新建Client.rb
好了现在保证服务端 server运行正常 ruby Client.rb
服务端就会打印出Its just a test!from ruby ice client
这里我们最终实现的其实是一个很简单的东西,服务端接收到客户端传来的两个字符串,然后拼装打印出来。但是可以让我们初步了解一下Ice究竟是个什么东东
之前经常听到同事说,Ice调用起来很简单的…… Ice性能相当牛X…… 等等
这两天学习下来,也看了些例子,发现Ice简单的调用是不怎么难,有现成的公式可以套。但是还是有很多东西不明白,里面应该还有很多博大精深的东东,需要自己一点点的去琢磨。
给自己加个油先,努力学习中……
接下来贴上我所有环境的搭建过程以及代码,和大家分享下ICE所带来的快乐
ICE是什么我就不多说了
想知道更多请去http://www.zeroc.com/
我这里用了两台机器,一台是linux rdhl5 一台是xp 在linux上跑一个C++服务端程序和一个C++客户端程序,xp上跑一个ruby客户端程序
首先开始搭建环境……
1、linux上ICE环境
http://www.zeroc.com/download/Ice/3.3/Ice-3.3.1-rhel5-i386-rpm.tar.gz
解开之后包含以下文件
[root@localhost tmp]# tar -zxvf Ice-3.3.1-rhel5-i386-rpm.tar.gz
db46-4.6.21-3ice.rhel5.i386.rpm
db46-devel-4.6.21-3ice.rhel5.i386.rpm
db46-java-4.6.21-3ice.rhel5.i386.rpm
db46-utils-4.6.21-3ice.rhel5.i386.rpm
ice-3.3.1-1.rhel5.noarch.rpm
ice-c++-devel-3.3.1-1.rhel5.i386.rpm
ice-java-3.3.1-1.rhel5.noarch.rpm
ice-java-devel-3.3.1-1.rhel5.i386.rpm
ice-libs-3.3.1-1.rhel5.i386.rpm
ice-php-3.3.1-1.rhel5.i386.rpm
ice-python-3.3.1-1.rhel5.i386.rpm
ice-python-devel-3.3.1-1.rhel5.i386.rpm
ice-ruby-3.3.1-1.rhel5.i386.rpm
ice-ruby-devel-3.3.1-1.rhel5.i386.rpm
ice-servers-3.3.1-1.rhel5.i386.rpm
ice-utils-3.3.1-1.rhel5.i386.rpm
mcpp-devel-2.7.2-1ice.rhel5.i386.rpm
特定语言的包你可以选择性安装
比如我这里服务端就跑C++ 所以这几个包我就可以不用装了
db46-java-4.6.21-3ice.rhel5.i386.rpm
ice-java-3.3.1-1.rhel5.noarch.rpm
ice-java-devel-3.3.1-1.rhel5.i386.rpm
ice-php-3.3.1-1.rhel5.i386.rpm
ice-python-3.3.1-1.rhel5.i386.rpm
ice-python-devel-3.3.1-1.rhel5.i386.rpm
ice-ruby-3.3.1-1.rhel5.i386.rpm
ice-ruby-devel-3.3.1-1.rhel5.i386.rpm
其他的几个包就都用RPM -ivh 安装吧 ,安装时候注意包之间的依赖关系,得按照顺序安装。默认会安装到/usr/ 目录下,执行文件在/usr/bin目录下 include lib分别在/usr/include 和 /usr/lib 这里不用我多说…… 执行下 slice2cpp 提示no input file 就证明ICE环境已经可以工作啦
下面我们来搭建服务端
1、先新建个ice文件 demo.ice
module Demo{ interface test{ string execute(string mth,string cmd); }; };
2、执行 slice2cpp demo.ice 执行成功后可以看到当前目录下生成了demo.cpp 和demo.h两个文件
3、新建Server.cpp
- #include
<Ice/Ice.h> - #include
<demo.h> - using
namespace std; - using
namespace Demo; - class
Server:public test - {
- public:
-
::std::string execute (const string & mth, const string & str, -
const Ice::Current &); - public:
-
Server (); - };
- Server::Server
() - {
-
- };
- std::string
Server::execute (const string & mth, const string & str, -
const Ice::Current &) - {
-
cout << mth + str << endl; -
return mth + str; - }
-
- int
main (int argc, char *argv[]) - {
-
int status = 0; -
Ice::CommunicatorPtr ic; -
try -
{ -
ic = Ice::initialize (argc, argv); - //ice接口服务启动在本地
监听10000端口 -
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","default -p 10000"); -
- //ice支持负载均衡
可以同时监听多端口,或者把server运行在多台主机上,用 tcp -h host -p port1:tcp -h host -p port2形式就可以了 如下同时监听10000和10001端口 -
//Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","tcp -h 10.1.151.3 -p 10000:tcp -h 10.1.151.3 -p 10001"); -
-
Ice::ObjectPtr object = new Server; - //注意这里tringToIdentity
("TestAdapter")); TestAdapter在客户端请求的时候用的到 -
adapter->add (object, ic->stringToIdentity ("TestAdapter")); -
adapter->activate (); -
ic->waitForShutdown (); -
} catch (const Ice::Exception & e) -
-
{ -
cerr << e << endl; -
status = 1; -
} catch (const char *msg) -
-
{ -
cerr << msg << endl; -
status = 1; -
} -
if (ic) -
{ -
try -
{ -
ic->destroy (); -
} -
catch (const Ice::Exception & e) -
{ -
cerr << e << endl; -
status = 1; -
} -
} -
return status; - }
#include <Ice/Ice.h> #include <demo.h> using namespace std; using namespace Demo; class Server:public test { public: ::std::string execute (const string & mth, const string & str, const Ice::Current &); public: Server (); }; Server::Server () { }; std::string Server::execute (const string & mth, const string & str, const Ice::Current &) { cout << mth + str << endl; return mth + str; } int main (int argc, char *argv[]) { int status = 0; Ice::CommunicatorPtr ic; try { ic = Ice::initialize (argc, argv); //ice接口服务启动在本地 监听10000端口 Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","default -p 10000"); //ice支持负载均衡 可以同时监听多端口,或者把server运行在多台主机上,用 tcp -h host -p port1:tcp -h host -p port2形式就可以了 如下同时监听10000和10001端口 //Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","tcp -h 10.1.151.3 -p 10000:tcp -h 10.1.151.3 -p 10001"); Ice::ObjectPtr object = new Server; //注意这里tringToIdentity ("TestAdapter")); TestAdapter在客户端请求的时候用的到 adapter->add (object, ic->stringToIdentity ("TestAdapter")); adapter->activate (); ic->waitForShutdown (); } catch (const Ice::Exception & e) { cerr << e << endl; status = 1; } catch (const char *msg) { cerr << msg << endl; status = 1; } if (ic) { try { ic->destroy (); } catch (const Ice::Exception & e) { cerr << e << endl; status = 1; } } return status; }
4、编译Server.cpp
执行g++ -I. -I/usr/include
接下来我们弄和服务端跑在一台机器上的c++客户端
1、新建Client.cpp
- #include
<string> - #include
<Ice/Ice.h> - #include
<demo.h> - using
namespace std; - using
namespace Demo; - int
main(void) -
- {
-
try { -
int argc=0; -
char* a=""; -
char** argv=&a; -
int status = 0; -
-
Ice::CommunicatorPtr ic; -
testPrx testServer; -
Ice::ObjectPrx base; -
-
ic = Ice::initialize(argc, argv); - //这里用到了TestAdapter
当然如果服务端支持多端口 那么客户端就可以用tcp -h 10.1.151.3 -p 10000:tcp -h 10.1.151.3 -p 100001 -
base = ic->stringToProxy("TestAdapter:tcp -h 10.1.151.3 -p 10000"); -
testServer = testPrx::checkedCast(base); - //这里我们调用了execute
-
string mystr = testServer->execute("Its just a test!","from cpp ice client"); -
-
printf("send:%s\n",mystr.c_str()); -
}catch (const Ice::Exception& ex) { -
cerr << ex << endl; -
} - }
#include <string> #include <Ice/Ice.h> #include <demo.h> using namespace std; using namespace Demo; int main(void) { try { int argc=0; char* a=""; char** argv=&a; int status = 0; Ice::CommunicatorPtr ic; testPrx testServer; Ice::ObjectPrx base; ic = Ice::initialize(argc, argv); //这里用到了TestAdapter 当然如果服务端支持多端口 那么客户端就可以用tcp -h 10.1.151.3 -p 10000:tcp -h 10.1.151.3 -p 100001 base = ic->stringToProxy("TestAdapter:tcp -h 10.1.151.3 -p 10000"); testServer = testPrx::checkedCast(base); //这里我们调用了execute string mystr = testServer->execute("Its just a test!","from cpp ice client"); printf("send:%s\n",mystr.c_str()); }catch (const Ice::Exception& ex) { cerr << ex << endl; } }
2、编译Client.cpp
执行g++ -I. -I/usr/include
好了 现在我们先执行下./server
每执行一次./client server端就会打印出Its just a test!from cpp ice client
再接下来我们来搞xp下ruby调用服务端ice接口
首先xp下安装ruby我就不用说了
下载one-click installer 安装 http://rubyforge.org/frs/download.php/47082/ruby186-27_rc2.exe
xp下搭建ice环境
下载支持ruby的版本 Ice-3.3.1-VC60.msi
http://www.zeroc.com/download/Ice/3.3/Ice-3.3.1-VC60.msi
安装完成之后做两件事情
1、set PATH=<Ice installation root directory>\bin;%PATH%
2、set RUBYLIB=<Ice installation root directory>\ruby;%RUBYLIB%
完成之后cmd下运行下slice2rb 发现有提示了
ruby运行一下 require'Ice' 没有报错 证明你xp下环境ok了
接下来是ruby调用服务端ice接口客户端实现
1、拿到上面服务端的demo.ice 我保存在E:\workspace\rubyforjason\Ice\目录下面 cmd运行下 slice2rb --output-dir E:\workspace\rubyforjason\Ice\ E:\workspace\rubyforjason\Ice\demo.ice
可以看到E:\workspace\rubyforjason\Ice\ 目录下生成了demo.rb这个文件
2、新建Client.rb
- require
'Ice' - #这里加载服务端给的ice文件
- Ice::loadSlice('demo.ice')
-
- status
= 0 - communicator
= nil -
- begin
-
communicator = Ice::initialize(ARGV) -
#这里要注意两点,1.这里的Demo::TestPrx从何而来?请查看 slice2XX 生成的文件 -
#2、TestAdapter从何而来?请查看服务端代码Server.cpp中Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","tcp -h 10.1.151.3 -p 10000"); 这一片段。这里用到了TestAdapter -
-
testServer = Demo::TestPrx::checkedCast(communicator.stringToProxy("TestAdapter:tcp -h 10.1.151.3 -p 10000")) -
#testServer = Demo::TestPrx::checkedCast(communicator.stringToProxy("TestAdapter:default -p 10000")) -
if not testServer -
puts $0 + ": invalid proxy" -
status = 1 -
else -
#其他的地方基本上都是公式化代码,在这里你才真正的调用服务端的接口 -
10.times{ -
puts testServer.execute("Its just a test!"," from ruby ice client") -
} -
end -
- rescue
=> ex -
puts $! -
puts ex.backtrace.join("\n") -
status = 1 - end
-
- if
communicator -
begin -
communicator.destroy() -
rescue => ex -
puts $! -
puts ex.backtrace.join("\n") -
status = 1 -
end - end
-
- exit(status)
require 'Ice' #这里加载服务端给的ice文件 Ice::loadSlice('demo.ice') status = 0 communicator = nil begin communicator = Ice::initialize(ARGV) #这里要注意两点,1.这里的Demo::TestPrx从何而来?请查看 slice2XX 生成的文件 #2、TestAdapter从何而来?请查看服务端代码Server.cpp中Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithE ndpoints ("TestAdapter","tcp -h 10.1.151.3 -p 10000"); 这一片段。这里用到了TestAdapter testServer = Demo::TestPrx::checkedCast(communicator.stringToProxy("TestAdapter:tcp -h 10.1.151.3 -p 10000")) #testServer = Demo::TestPrx::checkedCast(communicator.stringToProxy("TestAdapter:default -p 10000")) if not testServer puts $0 + ": invalid proxy" status = 1 else #其他的地方基本上都是公式化代码,在这里你才真正的调用服务端的接口 10.times{ puts testServer.execute("Its just a test!"," from ruby ice client") } end rescue => ex puts $! puts ex.backtrace.join("\n") status = 1 end if communicator begin communicator.destroy() rescue => ex puts $! puts ex.backtrace.join("\n") status = 1 end end exit(status)
好了现在保证服务端 server运行正常 ruby Client.rb
服务端就会打印出Its just a test!from ruby ice client
这里我们最终实现的其实是一个很简单的东西,服务端接收到客户端传来的两个字符串,然后拼装打印出来。但是可以让我们初步了解一下Ice究竟是个什么东东
之前经常听到同事说,Ice调用起来很简单的…… Ice性能相当牛X…… 等等
这两天学习下来,也看了些例子,发现Ice简单的调用是不怎么难,有现成的公式可以套。但是还是有很多东西不明白,里面应该还有很多博大精深的东东,需要自己一点点的去琢磨。
给自己加个油先,努力学习中……