- 浏览: 543879 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (340)
- Spring (4)
- Hibernate (2)
- Linux (34)
- Oracle (145)
- Eclipse (1)
- UML (1)
- HTML&&JAVASCRIPT (11)
- JAVA (33)
- 设计模式 (1)
- 版本控制 (1)
- wrap框架 (3)
- IBATIS (5)
- Ruby (1)
- DWR (1)
- MINA (11)
- JBPM (2)
- 缓存技术 (4)
- 网络 (3)
- 应用服务器 (1)
- GWT (5)
- 杂谈 (2)
- ICE (4)
- XML (2)
- ArcGis (2)
- Flex (8)
- junit单元测试 (1)
- SNMP (1)
- 存储 (1)
- office (1)
- MongoDB (0)
- Greenplum (3)
- 管理点滴 (1)
- C++ (6)
- 网络入门 (3)
- Tomcat (7)
- JMX (0)
- webservice (1)
- Oracle的10046事件 (1)
- Library cache内部机制详解 (1)
- expdp通过dblink来导入 (1)
最新评论
-
yuanliangding:
有没有关于mock的更多知识。
基于mock对象和JUnit框架简化Spring Web组件单元测试 -
saup007:
ssh端口不是22,怎么搞呢?
Greenplum 学习笔记 -
springmvc-freemarker:
java开源项目源码实例下载
Apache上全部JAVA开源项目简介 -
bobbell:
哇塞,你真厉害,整理的非常全面。我是一个java barcod ...
Greenplum 学习笔记 -
wsj55133245513324:
这不是bug,你将日志级别从debug提升到INFO 就好了 ...
Spring,smppapi,apache mina, ssl快速实现安全的smpp(5)
ICE的整体架构
服务器端:
服务器端通常只有一个通信器(Ice::Communicator),通信器包含了一系列的资源:
如线程池、配置属性、对象工厂、日志记录、统计对象、路由器、定位器、插件管理器、对象适配器
在通信器内,包含有一个或更多的对象适配器(Ice::ObjectAdapter),对象适配器负责提供一个或多个传输端点,并且把进入的请求分派到对应的servant中去执行。
具体实现的部分称为servant,它们为客户端发来的调用提供服务。servant向对象适配器注册以后,由对象适配器依据客户请求调用相应方法。
客户端:
客户端直接通过代理进行远程调用,就象本地调用一样简单。
通信器Ice::Communicator
通信器管理着线程池、配置属性、对象工厂、日志记录、统计对象、路由器、定位器、插件管理器、对象适配器。
通信器的几个重要方法:
std::string proxyToString(const Ice::ObjectPrx&) const; Ice::ObjectPrx stringToProxy(const std::string&) const;
这两个方法可以使代理对象和字符串之间互相转换。对于proxyToString方法,你也可以使用代理对象的 ice_toString方法代替(当然,你要确保是非空的代替对象)。
Ice::ObjectPrx propertyToProxy(const std::string&) const;
这个方法根据给定名字的属性配置生成一个代理对象,如果没有对应属性,返回一个空代理。
比如有如下属性:
MyApp.Proxy = ident:tcp -p 5000
我们就可以这样得到它的代理对象:
Ice::ObjectPrx p = communicator->propertyToProxy("MyApp.Proxy");
Ice::Identity stringToIdentity(const std::string&) const; std::string identityToString(const Ice::Identity&) const;
转换字符串到一个对象标识,对象标识的定义如下:
- namespace Ice
- {
- struct Identity
- {
- std::string name;
- std::string category;
- };
- }
当它与字符串相互转换时,对应的字符串形式是:CATEGORY/NAME。比如字符串“Factory/File”, Factory是category,File是name。
category部分可以为空。
Ice::ObjectAdapterPtr createObjectAdapter(const std::string&); Ice::ObjectAdapterPtr createObjectAdapterWithEndpoints( const std::string&, const std::string&);
这两个方法创建新的对象适配器。createObjectAdapter从属性配置中取得端点信息,而 createObjectAdapterWithEndpoints则直接指定端点。
void shutdown();
关闭服务端的Ice运行时库,调用shutdown后,执行过程中的操作仍可正常完成,shutdown不会等待这些操作完成。
void waitForShutdown();
这个方法会挂起发出调用的线程直到通信器关闭为止。
void destroy();
这个方法回收通信器的相关资源,如线程、通信端点及内存资源。在离开main函数之前,必须调用destory。
bool isShutdown() const;
如果shutdown已被调用过,则返回true。
初始化通信器
在建立通信器(Ice::Communicator)期间,Ice运行时会初始化一系列的对象,这些对象一直影响通信器的整个生命周期。并且在建立通信器以后,你不能改变这些对象。所以,如果你想定制这些对象,就必须在建立通信器的过程中定义。
在通信器建立期间,我们可以定义下面这些对象:
- 属性表(property)
- 日志记录器(Logger)
- 统计对象(Stats)
- 原生字符串与宽字符串转换器
- 线程通知钩子
所有上面的对象存放在InitializationData结构中,定义为:
- namespace Ice {
- struct InitializationData {
- PropertiesPtr properties;
- LoggerPtr logger;
- StatsPtr stats;
- StringConverterPtr stringConverter;
- WstringConverterPtr wstringConverter;
- ThreadNotificationPtr threadHook;
- };
- }
这个结构中的所有成员都是智能指针类型,设置好这些成员以后,就可以通过通信器的初始化函数传入这些对象:
- namespace Ice {
- CommunicatorPtr initialize(int&, char*[],
- const InitializationData& = InitializationData());
- CommunicatorPtr initialize(StringSeq&,
- const InitializationData& = InitializationData());
- CommunicatorPtr initialize(
- const InitializationData& = InitializationData());
- }
我们前面使用的Ice::Application也提供了InitializationData的传入途径:
- namespace Ice
- {
- struct Application
- {
- int main(int, char*[]);
- int main(int, char*[], const char*);
- int main(int, char*[], const Ice::InitializationData&);
- int main(const StringSeq&);
- int main(const StringSeq&, const char*);
- int main(const StringSeq&, const Ice::InitializationData&);
- ...
- };
- }
再回头看InitializationData结构:
properties:PropertiesPtr 类型,指定了属性表(property)对象,它就是之前《Ice属性配置》一文中的主角。默认的属性表实现可以解析“Key = Value”这种形式的字符串(包括命令行参数和文件),如果愿意,你可以自己写一个属性表实现,用来解析xml、ini等等。
如果要自己实现,就得完成下面这些接口(每个方法的作用请参考《Ice属性配置》):
- namespace Ice
- {
- class Properties : virtual public Ice::LocalObject
- {
- public:
- virtual std::string getProperty(const std::string&) = 0;
- virtual std::string getPropertyWithDefault(const std::string&,
- const std::string&) = 0;
- virtual Ice::Int getPropertyAsInt(const std::string&) = 0;
- virtual Ice::Int getPropertyAsIntWithDefault(const std::string&,
- Ice::Int) = 0;
- virtual Ice::StringSeq getPropertyAsList(const std::string&) = 0;
- virtual Ice::StringSeq getPropertyAsListWithDefault(const std::string&,
- const Ice::StringSeq&) = 0;
- virtual Ice::PropertyDict getPropertiesForPrefix(const std::string&) = 0;
- virtual void setProperty(const std::string&, const std::string&) = 0;
- virtual Ice::StringSeq getCommandLineOptions() = 0;
- virtual Ice::StringSeq parseCommandLineOptions(const std::string&,
- const Ice::StringSeq&) = 0;
- virtual Ice::StringSeq parseIceCommandLineOptions(const Ice::StringSeq&) = 0;
- virtual void load(const std::string&) = 0;
- virtual Ice::PropertiesPtr clone() = 0;
- };
- };
logger: LoggerPtr类型,这是一个日志记录器接口,它可以记录Ice运行过程中产生的跟踪、警告和错误信息,默认实现是直接向cerr输出。比如作用我们之前的Helloworld的例子,在没开服务端的情况下运行客户端,就看到在控制超台上打印了一串错误信息。
我们可以自己实现这个接口,以控制它的输出方向,它的定义为:
- namespace Ice
- {
- class Logger : virtual public Ice::LocalObject
- {
- public:
- virtual void print(const std::string& msg) = 0;
- virtual void trace(const std::string& category,
- const std::string& msg) = 0;
- virtual void warning(const std::string& msg) = 0;
- virtual void error(const std::string& msg) = 0;
- };
- }
不用说,实现它们是一件很轻松的事情^_^,比如你可以实现这个接口把信息写到一个日志文件里,或者把它写到某个日志服务器上。
stats: StatsPtr类型,当Ice发送或接收到数据时,会向Stats报告发生的字节数,这个接口更加简单:
- namespace Ice
- {
- class Stats : virtual public Ice::LocalObject
- {
- public:
- virtual void bytesSent(const std::string& protocol,
- Ice::Int num) = 0;
- virtual void bytesReceived(const std::string& protocol,
- Ice::Int num) = 0;
- };
- }
stringConverter:BasicStringConverter<char>类型;
wstringConverter:BasicStringConverter<wchar_t>类型;
这两个接口用于本地编码与UTF-8编码之间的转换,Ice系统自带了三套转换系统,默认的UnicodeWstringConverter、Linux/Unix 下使用的IconvStringConverter和Windows 下使用的WindowsStringConverter。
threadHook: ThreadNotificationPtr类型,线程通知钩子,当Ice建立一个新线程后,线程通知钩子就会首先得到“线程启动通知”,在结束线程之前,也能得到“线程结束通知”。
下面是ThreadNotification接口的定义:
- namespace Ice
- {
- class ThreadNotification : public IceUtil::Shared {
- public:
- virtual void start() = 0;
- virtual void stop() = 0;
- };
- }
假如我们在Windows下使用了COM组件的话,就可以使用线程通知钩子在start和stop里调用 CoInitializeEx和CoUninitialize。
代码演示
修改一下Helloworld服务器端代码,实现自定义统计对象(Stats,毕竟它最简单嘛-_-):
- #include <ice/ice.h>
- #include "printer.h"
- using namespace std;
- using namespace Demo;
- struct PrinterImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- cout << s << endl;
- }
- };
- class MyStats : public Ice::Stats {
- public:
- virtual void bytesSent(const string &prot, Ice::Int num)
- {
- cerr << prot << ": sent " << num << "bytes" << endl;
- }
- virtual void bytesReceived(const string &prot, Ice::Int num)
- {
- cerr << prot << ": received " << num << "bytes" << endl;
- }
- };
- class MyApp : public Ice::Application{
- public:
- virtual int run(int n, char* v[]){
- Ice::CommunicatorPtr& ic = communicator();
- ic->getProperties()->parseCommandLineOptions(
- "SimplePrinterAdapter", Ice::argsToStringSeq(n,v));
- Ice::ObjectAdapterPtr adapter
- = ic->createObjectAdapter("SimplePrinterAdapter");
- Ice::ObjectPtr object = new PrinterImp;
- adapter->add(object, ic->stringToIdentity("SimplePrinter"));
- adapter->activate();
- ic->waitForShutdown();
- return 0;
- }
- };
- int main(int argc, char* argv[])
- {
- MyApp app;
- Ice::InitializationData id;
- id.stats = new MyStats;
- return app.main(argc, argv, id);
- }
编译运行这个演示代码,然后执行客户端,可以看到打印出的接收到发送字符数。
tcp: send 14bytes tcp: received 14bytes tcp: received 52bytes tcp: send 26bytes tcp: received 14bytes tcp: received 53bytes Hello World! tcp: send 25bytes tcp: received 14bytes
对象适配器(Ice::ObjectAdapter)
对象适配器负责提供一个或多个传输端点,并且把进入的请求分派到对应的servant中去执行。它的定义以及主要方法有:
- namespace Ice
- {
- struct ObjectAdapter : public LocalObject
- {
- // 返回适配器的名字(由Communicator::createObjectAdapter输入)
- std::string getName() const;
- // 返回创建并拥有应适配器的通信器
- Ice::CommunicatorPtr getCommunicator() const;
- // 激活处于hold状态的适配器。
- void activate();
- // 要求适配器进入hold状态,并马上返回
- void hold();
- // 等待直到适配器进入hold状态
- void waitForHold();
- // 要求适配器进入无效状态,一旦进入无效状态,就无法再次激活它,与该适配器关联的servant将会被销毁。
- void deactivate();
- // 等待直到适配器进入无效状态
- void waitForDeactivate();
- // 如果适配器处于无效状态,返回true
- bool isDeactivated() const;
- // 使适配器处于无效状态,并且释放所有的资源(包括适配器名)
- void destroy();
- // 使用指定的标识把servant注册到适配器中,返回该servant的代理
- Ice::ObjectPrx add(const Ice::ObjectPtr&, const Ice::Identity&);
- // 使用随机生成的UUID作为标识把servant注册到适配器中,返回该servant的代理
- Ice::ObjectPrx addWithUUID(const Ice::ObjectPtr&);
- // 从适配器中移除对应的servant
- Ice::ObjectPtr remove(const Ice::Identity&);
- // 查找对应标识的servant
- Ice::ObjectPtr find(const Ice::Identity&) const;
- // 查找代理对应的servant
- Ice::ObjectPtr findByProxy(const Ice::ObjectPrx&) const;
- // 把一个 Servant Locator 添加到这个对象适配器中。
- void addServantLocator(const Ice::ServantLocatorPtr&, const std::string&);
- // 查找一个已经安装到这个对象适配器中的 Servant Locator。
- Ice::ServantLocatorPtr findServantLocator(const std::string&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的代理
- Ice::ObjectPrx createProxy(const Ice::Identity&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的 " 直接代理 "。
- // 直接代理总是包含有当前的适配器端点。
- Ice::ObjectPrx createDirectProxy(const Ice::Identity&) const;
- // 创建一个与这个对象适配器及给定标识相匹配的 " 间接代理 "。
- // 间接代理只包含对象的标识和适配器名,通过定位器服务来得到服务器地址
- Ice::ObjectPrx createIndirectProxy(const Ice::Identity&) const;
- // 为这个对象适配器设置一个 Ice 定位器
- void setLocator(const Ice::LocatorPrx&);
- // 重新读入适配器的PublicshedEndpoints属性并更新内部的可用网络接口列表
- void refreshPublishedEndpoints();
- };
- }
Servant定位器
除直接向对象适配器注册servant以外,Ice允许我们向对象适配器提供一个Servant定位器。
有了Servant定位器以后,对象适配器得到一次请求时首先查找已注册的servant,如果没找到对应的servant,就会请求 Servant定位器提供servant。
采用这种简单的机制,我们的服务器能够让我们访问数量不限的servant:服务器不必为每一个现有的Ice对象实例化一个单独的 servant。
下面是Servant定位器的接口,我们必须自己实现这个接口:
- namespace Ice
- {
- class ServantLocator : virtual public Ice::LocalObject
- {
- // 只要有请求到达,而且适配器没有提供注册的条目,Ice就会调用locate。
- // locate的实现(由你在派生类中提供)应该返回一个能够处理该请求的 servant。
- // 通过cookie参数,你可以传入一个自定义指针数据,对象适配器并不在乎这个对象的内容
- // 当Ice 调用finished 时,会把你从locate 返回的cookie传回给你。
- virtual Ice::ObjectPtr locate(const Ice::Current& curr,
- Ice::LocalObjectPtr& cookie) = 0;
- // 一旦请求完成,Ice就会调用finished。
- // 把完成了操作的servant、该请求的Current 对象
- // 以及locate在一开始创建的 cookie 传给它。
- virtual void finished(const Ice::Current& curr,
- const Ice::ObjectPtr& obj, const Ice::LocalObjectPtr& cookie) = 0;
- // 当servant定位器所属的对象适配器无效时,Ice会调用deactivate方法。
- virtual void deactivate(const std::string&) = 0;
- };
- }
实现了ServantLocator后,通过对象适配器的addServantLocator方法注册到该适配器中。
在上面的接口中,有一个Ice::Current结构类型的参数,通过它,我们就可以访问“正在执行的请求”和“服务器中的操作的实现”等信息,Ice::Current的定义如下:
- namespace Ice
- {
- struct Current
- {
- // 负责分派当前请求的对象适配器
- Ice::ObjectAdapterPtr adapter;
- //
- Ice::ConnectionPtr con;
- // 当前请求的对象标识
- Ice::Identity id;
- // 请求的 facet
- std::string facet;
- // 正在被调用的操作的名字。
- std::string operation;
- // 操作的调用模式(Normal、Idempotent,或Nonmutating)
- Ice::OperationMode mode;
- // 这个调用的当前上下文,这是一个std::map类型的数据
- // 使用它就允许把数量不限的参数从客户发往服务器
- Ice::Context ctx;
- //
- Ice::Int requestId;
- };
- }
利用Ice::Current的id成员,我们可以得到所请求的对象标识,从而决定生产某个具体的Servant;使用ctx成员,我们还可以从客户端发送数据不限的“键值-数值”对到服务器中,实现灵活控制(甚至连方法参数都可以不用了,全部用ctx转送就行)。
例:向原HelloWorld 版服务器加入Servant定位器代码,当请求的标识的category为"Loc"时,由定位器返回对应的 servant。
服务器端
- #include <ice/ice.h>
- #include "printer.h"
- using namespace std;
- using namespace Demo;
- // 原打印版本
- struct PrinterImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- cout << s << endl;
- }
- };
- // OutputDebugString版本
- struct DbgOutputImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- ::OutputDebugStringA(s.c_str());
- }
- };
- // MessageBox版本
- struct MsgboxImp : Printer{
- virtual void printString(const ::std::string& s, const ::Ice::Current&)
- {
- ::MessageBoxA(NULL,s.c_str(),NULL,MB_OK);
- }
- };
- struct MyLocator : Ice::ServantLocator{
- virtual Ice::ObjectPtr locate(const Ice::Current& curr,
- Ice::LocalObjectPtr& cookie)
- {
- if(curr.id.name == "Dbg")
- return Ice::ObjectPtr(new DbgOutputImp);
- else if(curr.id.name == "Msg")
- return Ice::ObjectPtr(new MsgboxImp);
- else if(curr.id.name == "SimplePrinter")
- return Ice::ObjectPtr(new PrinterImp);
- else
- return NULL;
- }
- virtual void finished(const Ice::Current& curr,
- const Ice::ObjectPtr& obj, const Ice::LocalObjectPtr&)
- {
- }
- virtual void deactivate(const std::string& category)
- {
- }
- };
- class MyApp : public Ice::Application{
- public:
- virtual int run(int n, char* v[]){
- Ice::CommunicatorPtr& ic = communicator();
- ic->getProperties()->parseCommandLineOptions(
- "SimplePrinterAdapter", Ice::argsToStringSeq(n,v));
- Ice::ObjectAdapterPtr adapter
- = ic->createObjectAdapter("SimplePrinterAdapter");
- Ice::ObjectPtr object = new PrinterImp;
- adapter->add(object, ic->stringToIdentity("SimplePrinter"));
- // 注册MyLocator定位器,负责返回category为"Loc"的相应servant。
- adapter->addServantLocator(Ice::ServantLocatorPtr(new MyLocator),"Loc");
- adapter->activate();
- ic->waitForShutdown();
- return 0;
- }
- };
- int main(int argc, char* argv[])
- {
- MyApp app;
- return app.main(argc, argv);
- }
客户端代码与《ICE属性配置》中的代码相同,客户端命令行参数为
--MyProp.Printer="Loc/Msg:tcp -p 10000"
服务器端将会使用对话框显示“HelloWorld”。
对象代理(Object Proxy)
在客户端,我们使用对象代理进行远程调用,就如它们就在本地一样。但有时,网络问题还是要考虑的,于是Ice的对象代理提供了几个包装方法,以支持一些网络特性:
ice_timeout方法,声明为:Ice::ObjectPrx ice_timeout(int) const;返回一个超时代理,当在指定的时间(单位毫秒)内没有得到服务器端响应时,操作终止并抛出Ice::TimeoutException异常。
示例代码:
- Filesystem::FilePrx myFile = ...;
- FileSystem::FilePrx timeoutFile
- = FileSystem::FilePrx::uncheckedCast(
- myFile->ice_timeout(5000));
- try {
- Lines text = timeoutFile->read(); // Read with timeout
- } catch(const Ice::TimeoutException &) {
- cerr << "invocation timed out" << endl;
- }
- Lines text = myFile->read(); // Read without timeout
ice_oneway方法,声明为:Ice::ObjectPrx ice_oneway() const;返回一个单向调用代理。只要数据从本地端口发送出去,单向调用代理就认为已经调用成功。这意味着,单向调用是不可靠的:它可能根本没有发送出去 (例如,因为网络故障) ,也可能没有被服务器接受(例如,因为目标对象不存在)。好处是由于不用等服务端回复,能带来很大的效率提升。
示例代码:
- Ice::ObjectPrxo=communicator->stringToProxy(/* ... */);
- // Get a oneway proxy.
- Ice::ObjectPrx oneway = o->ice_oneway();
- // Down-cast to actual type.
- PersonPrx onewayPerson = PersonPrx::uncheckedCast(oneway);
- // Invoke an operation as oneway.
- try {
- onewayPerson->someOp();
- } catch (const Ice::TwowayOnlyException &) {
- cerr << "someOp() is not oneway" << endl;
- }
ice_datagram方法,声明为:Ice::ObjectPrx ice_datagram() const;返回数据报代理,它使用UDP传输机制,并且和单向调用代理一样,不会得到服务器端的答复,而且还有可能UDP包重复和不按次序到达服务端。
示例代码:
- Ice::ObjectPrxo=communicator->stringToProxy(/* ... */);
- // Get a datagram proxy.
- //
- Ice::ObjectPrx datagram;
- try {
- datagram = o->ice_datagram();
- } catch (const Ice::NoEndPointException &) {
- cerr << "No endpoint for datagram invocations" << endl;
- }
- // Down-cast to actual type.
- //
- PersonPrx datagramPerson = PersonPrx::uncheckedCast(datagram);
- // Invoke an operation as a datagram.
- //
- try {
- datagramPerson->someOp();
- } catch (const Ice::TwowayOnlyException &) {
- cerr << "someOp() is not oneway" << endl;
- }
批量调用代理:
Ice::ObjectPrx ice_batchOneway() const; Ice::ObjectPrx ice_batchDatagram() const; void ice_flushBatchRequests();
为了提供网络效率,对于单向调用,可以考虑把多个调用打包一起送往服务器,Ice对象代理提供了ice_batchOneway和ice_batchDatagram方法返回对应的批调用代理,使用这种代理时呼叫信息不会马上发出,而是等到调用ice_flushBatchRequests以后才一次性发出。
示例代码:
- Ice::ObjectPrx base = ic->stringToProxy(s);
- PrinterPrx printer = PrinterPrx::uncheckedCast(base->ice_batchOneway());
- if(!printer) throw "Invalid Proxy!";
- printer->printString("Hello");
- printer->printString("World");
- printer->ice_flushBatchRequests();
相关推荐
教程包括: 第一部分 Ice综述 第二部分 核心概念 第三部分 高级Ice 第四部分 Ice服务 附录ice各种配置说明
ICE学习资料ICE学习资料ICE学习资料ICE学习资料ICE学习资料ICE学习资料ICE学习资料ICE学习资料ICE学习资料
Ice-3.3.1 编译依赖第三方软件,安装Ice-3.3.1中间件必下载。
ice源码(Ice-3.4.1.tar.gz),源码,包括java,c++,perl,直接下载解压即可查看源码内容。可分析实现细节。绝对真实。
matlab ice.fig 函数源代码
里面有关于ice的教程以及ice中文版的手册,对ice的安装运行等都有很大的帮助,费尽了千辛万苦找来的资料。
ICE网络中间件。可以学习使用,更多资料请访问ICE官网。
更多来源:http://www.cnjhw.com 对方程序没用启用,也就是服务器没有启用: 发生在使用代理调用接口的时候 原因: 根本就没有相应的通讯器存在. 错误信息: 抛出异常: Ice::ConnectionRefusedException(很快) 6...
ICE最新版官方的学些资料,因为中文基本没有,一起啃吧
冈萨雷斯数字图像处理matlab版源码ice源码
为了配合ADS对通过JTAG接口对ARM进行调试,ARM公司特别推出了他们的官方仿真器Multi-ICE。 此资源是为了让更多用户对Multi-ICE有更多的了解。
ice demo是很好的学习ice的东西,ice是一个很好的分布式的网络通讯中间件,很好的支持跨平台等各种功能。 ice demo是很好的学习ice的东西,ice是一个很好的分布式的网络通讯中间件,很好的支持跨平台等各种功能。 ...
Ice通信框架简介;Ice通信框架简介;Ice通信框架简介
Ice 是一种面向对象的中间件平台。从根本上说,这意味着Ice 为构建面 向对象的客户-服务器应用提供了工具、API 和库支持。Ice 应用适合在异 种环境中使用:客户和服务器可以用不同的编程语言编写,可以运行在不 同...
Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice Ice
ICE开发文档 ICE开发文档 ICE开发文档 ICE开发文档
官方的提供的下载安装包不...及表现层(java,php,.net,python)进行更丰富的表现与操作,从而实现比较好的架 构。基于ICE的数据层可以在未来方便的进行扩展。ICE支持分布式的部署管理,消息中间件,以及网格计算等等。
Ice Ice-3.7.0 linux windows mac os docker java js python ruby source Download Ice 3.7 Version: 3.7.0 - July 21, 2017 You are licensing Ice under GPLv2 unless you purchase a commercial license.
IceCream Ebook Reader Pro中文版是一款运行在PC系统上的...冰淇淋电子书阅读器还包括翻页的能力,使用书签,搜索你的图书馆,跟踪阅读进步和更多功能等大家来发现. 包含多个注册机,注册当前IceCream公司的多个最新软件
ice ice-3.7.1 ice-3.7.1-msvc2015