http://www.acejoy.com/bbs/viewthread.php?tid=2878&extra=page%3D1
ICE开发初级研究(一)
最近一段一直在忙于工作,事情比较多,除了偶尔在这里看看帖子,一直没有写什么东西。再加上忙于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_H
module 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>
using namespace std;
using namespace Test;
class CTest : public TestICE
{
public:   
    int ping(const Ice::Current&);    
    int GetTime(string& strTime, const Ice::Current&);
};
这样,一个ICE的接口对象,就和你的实际方法绑定成功了。实现么,呵呵,你可以自己去写啦。
然后先看看服务器的源码。
class CMainServer : public Ice::Application
{
public:
    virtual int run(int, char*[]);
};

int CMainServer::run(int argc, char* argv[])
{
    try        
    {
        Ice::ObjectAdapterPtr AdaptrPtr = communicator()->createObjectAdapter("SampleTest");                
        Ice::ObjectPtr Object = new CTest;                
        AdaptrPtr->add(Object, communicator()->stringToIdentity("SampleTest"));                
        AdaptrPtr->activate();                
        communicator()->waitForShutdown();                
        return EXIT_SUCCESS;        
    }        
    catch(const Ice::Exception ex)        
    {                
        printf("[Main]Error = %s.\n", ex);                
        return -1;        
    }
}

int main(int argc, char* argv[])
{        
    CMainServer app;
    app.main(argc, argv, "init.config");
    getchar();
    return 0;
}

这里的代码其实挺简单的,代码基本是固定的。
你需要的是修改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
客户端代码也不复杂。
class CMainClient : public Ice::Application
{
public:
    virtual int run(int, char*[]);
};

int CMainClient::run(int argc, char* argv[])
{
    try
    {
        string strData = "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");
            return EXIT_FAILURE;
        }

int nData = testice->GetTime(strData);
        printf("[CMainClient::run]GetTime is %d.\n", nData);

return EXIT_SUCCESS;
    }
    catch(const Ice::Exception ex)
    {
        printf("[Main]Error = %s.\n", ex.what());
        return -1;
    }
}

int main(int argc, char* argv[])
{
    CMainClient app;
    app.main(argc, argv, "init.config");
    getchar();
    return 0;
}

这里面大部分代码都是固定的,依然只是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下测试通过。

三 ICE开发初级研究的更多相关文章

  1. iOS企业级开发初级课程-表视图(13集)

    首先了解了表视图的组成.表视图类的构成.表视图的分类以及表视图的两个重要协议(委托协议和数据源协议),对表视图有了一个整体上的认识.接下来我们掌握了如何实现简单表视图和分节表视图,以及表视图中索引.搜 ...

  2. 20145213《Java程序设计》实验三敏捷开发与XP实践

    20145213<Java程序设计>实验三敏捷开发与XP实践 实验要求 1.XP基础 2.XP核心实践 3.相关工具 实验内容 1.敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法 ...

  3. 20162311 实验三 敏捷开发与XP实践 实验报告

    20162311 实验三 敏捷开发与XP实践 实验报告 实验内容 一.研究学习IDEA中的Code菜单 使用Code ->Reformate Code功能将以下代码格式化 public clas ...

  4. APP的三种开发模式

    转载于http://pleasureswx123.github.io/2014/09/15/APP%E7%9A%84%E4%B8%89%E7%A7%8D%E5%BC%80%E5%8F%91%E6%A8 ...

  5. #实验三 敏捷开发与XP实践---实验报告

    一.实验三 敏捷开发与XP实践-1 1.实验要求 -实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成I ...

  6. 20165223 实验三 敏捷开发与XP实践

    目录 一.实验报告封面 二.具体实验内容 (一)敏捷开发与XP实践-1 代码规范格式化 (二)敏捷开发与XP实践-2 添加搭档项目 (三)敏捷开发与XP实践-3 搭档代码重构 (四)敏捷开发与XP实践 ...

  7. 20165337实验三——敏捷开发与XP实践

    实验要求 实验三-1 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参考 http://www.c ...

  8. 20165323 实验三 敏捷开发与XP实践

    一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:杨金川 学号:20165323 指导教师:娄嘉鹏 实验日期:2018年4月28日 实验时间:13:45 - 15:25 实验序号:实验 ...

  9. 20165220 实验三 敏捷开发与XP实践 实验报告

    实验三 敏捷开发与XP实践-1 实验要求: 实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA ...

随机推荐

  1. highchart 实现mrtg

    最近需要对流量图进行重构, <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  2. java BingInteger生成2进制String循环移位时长度自动缩减

    最近在做文本处理,使用MD5 生成一段文字的MD5哈希长度为32位也即128个0-1序列. 由于需要对这个MD5值进行循环移位,显然普通的  int 是不行的,所以使用 BigInteger.但是在使 ...

  3. Guice 学习(六)使用Provider注入服务( Provider Inject Service)

    1.定义接口 package com.guice.providerInject; import com.google.inject.ProvidedBy; public interface Servi ...

  4. OJ2.0userInfo页面Modify逻辑bug修复,search功能逻辑实现

    这周的主要任务:userInfo页面Modify逻辑bug修复,search功能逻辑实现. (一)Modify逻辑bug修复: 这里存在的bug就是在我们不重置password的时候依照前面的逻辑是不 ...

  5. 【转载】laravel的MVC

    http://my.oschina.net/tongjh/blog/194231 http://baike.baidu.com/view/1020297.htm 一.laravel路由(应用中的大多数 ...

  6. Android应用程序的Activity启动过程简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...

  7. 面试前的准备---C#知识点回顾----05

    技术博客还得继续写,工作还在筛选,学习还得继续 1.Session和Cookie的使用区别 很容易回答的就是Session在服务器端,存储的数据可以较大容量,比如我们存一个Table,上千条数据. C ...

  8. CLR via C# - 基础拾遗

    编译器开关设置 IL代码质量 JIT本地代码质量 /optimize- /debug-(默认设置) 未优化 优化 /optimize- /debug+(full/pdbonly) 未优化 未优化 /o ...

  9. 关于object在使用上的问题

    关于object在使用上的问题 1.直接调用标签<object>中的单击事件 <object>是含有onclick和ondblclick两个事件的.按照以往方式,直接在里面调用 ...

  10. libxml两种换行方法

    好久没上来留下一些记录了,可能是太忙,又或者是过于慵懒便疏于整理. libxml是一个开源的库,linux下解析xml文件经常用到,进行一些创读增删的操作. 最开始接触的时候,看到了一个简明易懂的&l ...