分布式rpc框架ice学习之helloworld篇

c/c++

浏览数:289

2019-4-1

更多相关内容 http://www.codefrom.com/

官方安装文档在:https://zeroc.com/download.html
这里根据官方文档,演示在mac平台的安装教程,
使用 Homebrew直接安装如下:

brew install ice

在homebrew下载过程中,可能有些文件由于某些原因下载不下来,我这里文件mcpp-2.7.2.tar.gz就下载不了,挂上代理直接下载,然后运行命令

sudo cp -f ~/Downloads/mcpp-2.7.2.tar.gz /Library/Caches/Homebrew/mcpp-2.7.2.tar.gz

同样的方法,其他不能下载的也可以通过挂代理下载后拷贝到对应的地方完成安装。
安装好了,我的mac会自动在/usr/local/Cellar/ice/3.5.1_1/
目录下(版本3.5)有相应的编译需要的头文件。
在这里根据官方的文档进行php和c++的通讯,文档地址:https://doc.zeroc.com/pages/viewpage.action?pageId=14030991

第一步,编写ice的slice配置文件,如下:

module Demo {
    interface Printer {
        void printString(string s);
    };
};

表明Demo模块下存在一个接口Printer,提供一个操作printString
第二步,编译该文件生成对应语言源文件,c++源文件命令如下:

slice2cpp Printer.ice

会生成两个c++文件,如下:

Printer.cpp  Printer.h

然后编写服务端,命名为Server.cpp,代码如下:

#include <Ice/Ice.h>
#include <Printer.h>

using namespace std;
using namespace Demo;

class PrinterI : public Printer {
    public:
        virtual void printString(const string& s, const Ice::Current&);
};

void 
PrinterI::printString(const string& s, const Ice::Current&)
{
    cout << s << endl;
}

int main(int argc, char* argv[])
{
    int status = 0;
    Ice::CommunicatorPtr ic;
    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectAdapterPtr adapter =
            ic->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");
        Ice::ObjectPtr object = new PrinterI;
        adapter->add(object, ic->stringToIdentity("SimplePrinter"));
        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;
}
服务端实现的printString功能很简单,直接输出参数内容。

编译命令如下:

c++ -I. -I/usr/local/Cellar/ice/3.5.1_1/include -c Printer.cpp Server.cpp
c++ -o server Printer.o Server.o -L/usr/local/Cellar/ice/3.5.1_1/lib -lIce -lIceUtil

会生成server二进制文件服务端,运行./server命令即可监听本地10000 端口。
第三步,编写客户端。
c++客户端代码如下:

#include <Ice/Ice.h>
#include <Printer.h>

using namespace std;
using namespace Demo;

int main(int argc, char* argv[])
{
    int status = 0;
    Ice::CommunicatorPtr ic;
    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000");
        PrinterPrx printer = PrinterPrx::checkedCast(base);
        if (!printer)
            throw "Invalid proxy";

        printer->printString("Hello World!");
    } catch (const Ice::Exception& ex) {
        cerr << ex << endl;
        status = 1;
    } catch (const char* msg) {
        cerr << msg << endl;
        status = 1;
    }
    if (ic)
        ic->destroy();
    return status;
}

客户端调用printString方法传入参数为“Hello World!”,编译命令同理如下:

c++ -I. -I/usr/local/Cellar/ice/3.5.1_1/include -c Printer.cpp Client.cpp
c++ -o client Printer.o Client.o -L/usr/local/Cellar/ice/3.5.1_1/lib -lIce -lIceUtil

运行生成的client二进制文件,./client可以看到server端显示如下:

可以看到客户端调用printer的接口printString成功
下面演示php的客户端代码编写。首先运行命令

slice2php Printer.ice

会在当前目录下生成Printer.php,然后编写客户端代码client.php如下:

<?php
ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . '/usr/local/Cellar/ice/3.5.1_1/php/');
require 'Ice.php';
require 'Printer.php';

$ic = null;
try
{
    $ic = Ice_initialize();
    $base = $ic->stringToProxy("SimplePrinter:default -p 10000");
    $printer = Demo_PrinterPrxHelper::checkedCast($base);
    if(!$printer)
        throw new RuntimeException("Invalid proxy");

    $printer->printString("Hello World!");
}catch(Exception $ex){
}

直接调用php client.php同样可以看到服务端显示“Hello World!”
由此,可以看到,利用ice,php成功调用了c++实现的Printer接口的printString方法。
注:/usr/local/Cellar/ice/3.5.1_1/是我本机地址。