Ice介绍
Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件。Ice是RPC通讯领域里最稳定、强大、高性能、跨平台、多语言支持的老牌开源中间件,特别适合于当前互联网领域中一个平台存在多种开发语言编程,以及网站和app应用并存的复杂大型项目。
RPC(Remote Procedure Call Protocol 远程过程调用协议),是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC假定某些传输协议的存在,如TCP或UDP,为通讯程序之间携带信息数据;在OSI网络通讯模型中,RPC跨越了传输层和应用层。
Ice通过与编程语言无关的中立语言Slice(Specification Language fro Ice)来描述服务的接口,从而达到对象接口与其实现想分离的目的。
目前Ice平台支持客户端API的语言有C++、.NET、Java、Python、Object-C、Ruby、PHP、JavaScript等。在服务器可以使用C、.NET、Java、Python等来开发。
关键特性
1. 支持多语言之间的RPC互通。
2. 高性能的RPC调用。
3. 支持传统的RPC调用、异步调用、One-Way调用、批量发起请求,支持TCP通信、UDP通信等。
4. 多平台支持。
5. 不断更新,与时俱进。
通讯原理
1. 开发者通过slice定义接口规范Printer.ice。
2. 客户端和服务端分别通过对应的转换工具生成各自语言的接口。
3. 客户端和服务器分别用各自的语言根据统一的接口实现具体逻辑代码。
至于调用等底层实现由ICE帮我们完成,大大简化、节省了开发的时间。
我的安装环境: win7 ,visual studio 2015,zeroc 3.7
服务端语言:C++
客户端语言:C#
接口(计算两整数值,服务端计算,客户端调用接口)
module AddT
{
interface Adder
{
int add(int i,int j);
}
}
ice配置
1、ICE安装(去官网下载最新版本,此次版本只有20M,之前版本将近400M,主要是把C++库文件放在其它地方了)
1、进入程序包管理器(工具->NuGet包管理器->程序包管理器控制台)
2、安装ice、ice builder、ice插件
2.1、安装ice,选择项目,输入install-package zeroc.ice.v140 -version 3.7.1
Tips:V140代表VS的版本,(V140<->VS2015,V120<->VS2013),3.7.1代表ice的版本
2.2、安装ice.builder.msbuild,输入install-package zeroc.icebuilder.msbuild
2.3、 安装ice build插件
服务端
1.1、修改项目属性
1.1.2、包含ice输出目录
将接口文件 Add.ice 添加到工程,如下:
这时编译,出现下述错误:
查了一下午原因,原来是使用了预编译,关掉如图:
这时可以编译通过。
好了,可以写服务端代码,如下:
#include "stdafx.h"
#include <Ice/Ice.h>
#include "Add.h"
#include<iostream>
using namespace AddT;
using namespace std;
class AdderI :public AddT::Adder
{
public:
virtual int add(int i, int j, const Ice::Current&);
};
// 这里就是RPC接口的实现代码
int AdderI::add(int i, int j, const Ice::Current&)
{
// 这个接口实现的功能非常简单:在标准输出上打印接收到的字符串
int sum = i + j;
return sum;
}
int main()
{
Ice::CommunicatorPtr ic;
ic = Ice::initialize();
Ice::ObjectAdapterPtr adapter =
ic->createObjectAdapterWithEndpoints("AdderAdapter", "tcp -p 20000");
// 实例化一个PrinterI对象,该对象将为接口Printer提供服务
auto servant(make_shared<AdderI>());
// 把PrinterI对象加入ObjectAdapter,标识名为SimplePrinter。当有客户端请求Printer的服务时,ObjectAdapter将会把请求转给PrinterI对象
adapter->add(servant, Ice::stringToIdentity("Adder"));
// 启动ObjectAdapter, 此后ObjectAdapter开始处理实际的调用请求
adapter->activate();
// 阻塞主线程,直到服务端的运行时被关闭
ic->waitForShutdown();
return 0;
}
此代码正常运行通过
客户端
又折腾了很久,主要不知道怎么生成接口文件,最后看了他人示例,用命令生成,如下:
生成的 Add.cs 文件在 我的文档 目录下
客户基本结构最后是这样:
如果没有安装Ice c#的库,代码也编译不过,需要用Visual Studio 2015自带的工具NuGet,如下图:
装上这两个插件,好了,可以编译通过。
主程序代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AddT;
namespace ClientIce
{
class Program
{
static void Main(string[] args)
{
using (Ice.Communicator communicator = Ice.Util.initialize())
{
var obj2 = communicator.stringToProxy("Adder:tcp -h 127.0.0.1 -p 20000");
int i = 1;
int j = 2;
var adder = AdderPrxHelper.checkedCast(obj2);
if (adder == null)
{
throw new ApplicationException("Invalid proxy");
}
int sum = adder.add(i, j);
Console.WriteLine(sum);
}
}
}
}
最后
先开服务端,再开客户端,如下图: