此处案例将ICE接口当做单servant使用(ICE自带端口复用的多servant,过于复杂,此处不讨论)

使用ICE较为方便的地方时 可以编写 ice中间代码,然后由官方工具转换为目标平台代码(通过语句自动生成),生产的代码结构比较复杂,不赘述,此处需要注意一点,自动生成的文件夹路径不要包含特殊字符。

ICE的使用概念与传统的RPC框架没有差异。过程如下:

1、由某一方建立监听,作为通讯宿主(习惯称之为服务器)

2、由另外一方建立链接到服务器(习惯称之为客户端)

3、客户端向服务器注册自己的信息(可能会有多个客户端,意味着可以注册多个客户,服务器需要存储)

4、双向自由互调。

其中双向互调过程中,主动发起调用方名义上都叫做 client ,提供服务方 都叫做 servant。

双方需要有一个约定,即上面提到的自动生成的 <interface>Disp_ 抽象类,作为双方统一接口。双方均需要定义自己的服务去实现该抽象类(client/servant 作用不同,实现的方式自然不同)。

为了满足多个不同端口不通服务使用,笔者对客户端和服务器进行了简单封装,如下

需要改进重连机制

public class ICEClient<T,TPrx>
{
public TPrx Server { get; private set; } public bool Online { get; private set; } ILog _Logger = Spv2LoggerFactory.GetLoggerByName("RPC"); string _IPAddress;
int _Port;
int connectTimeout = 60000;
int idleTimeout = -1; //no limit public ICEClient(string ip, int port)
{
_IPAddress = ip;
_Port = port;
} /// <summary>
///
/// </summary>
/// <param name="Servant"> 作为服务端接收指令响应</param>
public void Connect(T Servant=default(T))
{
if (Online)
{
_Logger.InfoFormat("Initializing, Online!");
return;
}
try
{
_Logger.InfoFormat("Initializing ICE Comm using Host: {0}, Port: {1}, connectTimeout: {2}, idleTimeout: {3}",
_IPAddress, _Port, connectTimeout, idleTimeout); // TODO figure out how to use properties.
Ice.InitializationData id = new Ice.InitializationData();
id.properties = Ice.Util.createProperties();
id.properties.setProperty("Ice.Default.ConnectTimeout", connectTimeout.ToString());
id.properties.setProperty("Ice.Default.Timeout", idleTimeout.ToString()); // 5 min?
id.properties.setProperty("Ice.Warn.UnusedProperties", "1");
id.properties.setProperty("Ice.Warn.Host", _IPAddress); var _ICEComm = Ice.Util.initialize(id); string connectString = String.Format("{0}:tcp -p {1} -h {2}", typeof(T).Name, _Port, _IPAddress);
ObjectPrx iceProxy = _ICEComm.stringToProxy(connectString); Server = CreateServerProxy(iceProxy); _Logger.InfoFormat("ICE check proxy cast finished. {0}", _IPAddress);
if (Server == null)
{
_ICEComm.destroy();
_ICEComm = null;
id = null;
GC.Collect();
throw new System.Exception("Invalid proxy");
} if(Servant!=null)
{
Ice.ObjectAdapter iceAdapter = _ICEComm.createObjectAdapter("");
iceAdapter.add((Ice.Object)Servant, iceProxy.ice_getIdentity());
iceProxy.ice_getConnection().setAdapter(iceAdapter);
iceAdapter.activate();
}
}
catch (System.Exception ex)
{
Online = false;
GC.Collect();
string errorMsg = String.Format("System Exception {0} caught.", ex.Message);
_Logger.Error(errorMsg);
throw;
}
Online = true;
} private TPrx CreateServerProxy(ObjectPrx iceProxy)
{
//TestICEPrxHelper
var str = typeof(TPrx).FullName + "Helper";
var type = Type.GetType(str);
var serverproxy = Activator.CreateInstance(type); //static method
var method = type.GetRuntimeMethod("uncheckedCast", new Type[] { typeof(ObjectPrx) }); return (TPrx)method.Invoke(type, new[] { iceProxy });
}
}
public class ICEServer<T,TPrx>
{
ILog _Logger = Spv2LoggerFactory.GetLoggerByName("RPC"); /// <summary>
/// 客户端的集合
/// </summary>
public Dictionary<string,TPrx> Clients { get; set; } = new Dictionary<string, TPrx>(); string _IPAddress;
int _Port; public ICEServer(string ip, int port)
{
_IPAddress = ip;
_Port = port;
} /// <summary>
///
/// </summary>
/// <param name="Servant"> 作为服务端接收指令响应</param>
public void StartUp(T Servant)
{
try
{
_Logger.InfoFormat("Initializing ICE Comm using Host: {0}, Port: {1}",_IPAddress, _Port); var _ICEComm = Ice.Util.initialize();
Ice.Communicator iceComm = Ice.Util.initialize();
// Create adaptor for commands and requests from client Ice.ObjectAdapter iceAdapter = iceComm.createObjectAdapterWithEndpoints(typeof(T).Name, $"tcp -p {_Port} -h {_IPAddress}");
iceAdapter.add((Ice.Object)Servant, iceComm.stringToIdentity(typeof(T).Name));
iceAdapter.activate();
}
catch (System.Exception ex)
{
GC.Collect();
string errorMsg = String.Format("System Exception {0} caught.", ex.Message);
_Logger.Error(errorMsg);
throw;
}
}
}

以下为测试代码

// Copyright 2016 Complete Genomics, Inc.  All Rights Reserved.
// Confidential and proprietary works of Complete Genomics, Inc. module My {
module RPC {
interface TestICE
{
void AddClient(string name); string ClientCallServer(int i); void ServerCallClient(int i);
};
};
};
    internal class TestICEServer : TestICEDisp_
{
ICEServer<TestICE, TestICEPrx> server;
internal TestICEServer()
{
server = new ICEServer<TestICE, TestICEPrx>("172.16.35.66", 11106);
server.StartUp(this);
}
public override void AddClient(string name, Current current__)
{
Ice.ObjectPrx @base = current__.con.createProxy(current__.id);
var client = TestICEPrxHelper.checkedCast(@base);
server.Clients.Add(name, client);
} public override string ClientCallServer(int i, Current current__)
{
return (++i).ToString();
} public override void ServerCallClient(int i, Current current__)
{
foreach (var client in server.Clients.Values)
{
client.ServerCallClient(i);
}
}
} public class TestServerService : TestICEOperationsNC_
{
TestICEServer server;
public TestServerService()
{
server = new TestICEServer();
} public void AddClient(string name)
{
server.AddClient(name);
} public string ClientCallServer(int i)
{
return server.ClientCallServer(i);
} public void ServerCallClient(int i)
{
server.ServerCallClient(i);
}
}
    internal class TestICEClient : TestICEDisp_
{
ICEClient<TestICE, TestICEPrx> client;
internal TestICEClient()
{
client = new ICEClient<TestICE, TestICEPrx>("172.16.35.66", 11106);
client.Connect(this);
}
public override void AddClient(string name, Current current__)
{
client.Server.AddClient(name);
} public override string ClientCallServer(int i, Current current__)
{
var r= client.Server.ClientCallServer(i);
return r;
} public override void ServerCallClient(int i, Current current__)
{
var r = i;
}
} public class TestICEClientService : TestICEOperationsNC_
{
TestICEClient server;
public TestICEClientService()
{
server = new TestICEClient();
} public void AddClient(string name)
{
server.AddClient(name);
} public string ClientCallServer(int i)
{
return server.ClientCallServer(i);
} public void ServerCallClient(int i)
{
server.ServerCallClient(i);
}
}

zeroc ICE 使用案例的更多相关文章

  1. ZeroC Ice 暂记

    摘自: http://weibo.com/p/1001603869896789339575 原文地址: http://www.oschina.net/question/865233_242146 吴治 ...

  2. ZeroC Ice启用SSL通讯的配置

    Zeroc ICE ( Internet Communications Engine )中间件号称标准统一,开源,跨平台,跨语言,分布式,安全,服务透明,负载均衡,面向对象,性能优越,防火墙穿透,通讯 ...

  3. ZEROC ICE 跨平台间程序调用 java版

    前言: 本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE. 最近一个项目涉及到java.python ...

  4. Zeroc Ice Slice语言使用 HelloWorld

    Slice介绍         为了开发多语言支持的RPC服务,需要一种中立的新语言来定义这个服务接口,以便各个编程语言能够准确无误地理解和翻译接口,为此Ice设计了Slice语言.Ice开发的第一步 ...

  5. Zeroc Ice原理介绍

    Ice介绍         Ice(Internet Communications Engine)是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件.Ice是RPC通 ...

  6. ZeroC Ice IceGrid Node和IceGrid

    IceGrid Node介绍 绝大多数分布式系统都有一个共同特点,即分布在各个主机上的节点进程并不是完全独立的,而是彼此之间有相互联系和通信的.集群对集群中的节点有一些控制指令,如部署.启停或者调整某 ...

  7. ZeroC Ice Ice Registry实现负载均衡

    Registry介绍         对于多个IceBox集群该怎么负载均衡?以服务注册表Registry为依托的Service Locator组件,以及依赖其而诞生的强大的分分布式框架-IceGri ...

  8. ZeroC Ice IceBox使用

    IceBox介绍 IceBox就像一个Tomcat,我们只要写N个Ice服务代码,用一个装配文件定义需要加载的服务列表.服务器的启动参数.启动次序等必要信息,然后启动IceBox,我们的应用系统就能够 ...

  9. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

随机推荐

  1. 高并发&性能优化(二)------系统监控工具使用

    上一篇主要从总体介绍了高并发&性能优化的相关思路和方法,本篇主要介绍系统监控工具. [CPU查看工具] ------top命令(性能) 进入top命令后,按1即可看到每核CPU的运行指标与详细 ...

  2. #企业项目实战 .Net Core + Vue/Angular 分库分表日志系统六 | 最终篇-通过AOP自动连接数据库-完成日志业务

    教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...

  3. 23种设计模式 - 组件协作(TemplateMethod - Observer/Event - Strategy)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 组件协作 现代软件专业分工之后的第一个结果是"框架与应用程序的划分","组件 ...

  4. 【Flutter 实战】17篇动画系列文章带你走进自定义动画

    老孟导读:Flutter 动画系列文章分为三部分:基础原理和核心概念.系统动画组件.8篇自定义动画案例,共17篇. 动画核心概念 在开发App的过程中,自定义动画必不可少,Flutter 中想要自定义 ...

  5. guzzle下载图片(laravel+vue)

    先再laravel安装guzzle扩展包:composer require guzzlehttp/guzzle 之后再控制器操作: use GuzzleHttp\Client; //远程api数据的获 ...

  6. 使用rabbitmq过程中遇到的问题及解决方法记录。

    OS: Linux ---Centos7RabbitMQ版本:RabbitMQ version: 3.8.1erlang版本:Erlang configuration: Erlang/OTP 22 [ ...

  7. Java使用POI的SXSSFWorkbook与HSSFWorkbook导出复杂表头

    一.HSSFWorkbook与SXSSFWorkbook的区别: HSSFWorkbook是对Excel2003以前的版本进行操作的,即后缀名为.xls SXSSFWorkbook时对Excel200 ...

  8. Java8 日期和时间类

    新的日期和时间API 新的日期和时间类解决了Date和Calendar类出现的问题 浅尝 LocalDate 日期类 LocalDate of = LocalDate.of(2018, 7, 13); ...

  9. C011:分数相加

    代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int up1,down1,up2,down2; do ...

  10. console线和RJ45

    123 前言 一直以为console口和RJ45是同一种接口,but后来我发现我错了~ RJ45 先介绍一下RJ45吧 什么是RJ45? RJ45是一种接口 我们家用的网线的接口 其实就是RJ45 r ...