此处案例将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. Java--- 关于null的处理若干方法

    Java--- 关于null的处理若干方法 相信空指针是平时最常见的错误了,下面认识 null ,有助于解决 NPE 问题. nulll大小写敏感 关于这个问题,其实是对面试时候手写算法题时候需要注意 ...

  2. Windows servers 2008 环境下,域控DC和DNS,分离搭建过程。

    近来做有关于window服务器方面运维的实验,正好借此记录下来,便于日后回顾. 通常情况下,域控DC服务器和DNS服务器一般不在一起,所以需要将其分开建立.而这个时候两个服务器的建立有先后顺序,本文会 ...

  3. SEO需要分析哪些网站数据

    http://www.wocaoseo.com/thread-227-1-1.html 一.网站的基本数据 1.网站流量详情(ip.pv.需要看pv与ip的比) 2.网站的跳出率(可以看出一个网站的用 ...

  4. source insight4提示结尾不一致。关闭

    source insight4提示结尾不一致.关闭.世界清静了. Options -> Preferences ->Files  最后的Ask to fix inconsistent li ...

  5. oeasy教您玩转linux010105详细手册man

    详细手册 回忆上节课 我们上节课学习了使用命令来了解命令 whatis 我们通过他来发出灵魂之问 whatis到底是干什么的?

  6. LoadRunner回放脚本遇到的问题(遇到就补上)

    问题一:Error-26612:HTTP Status-code=500(Internal Server Error) 解决过程:google找到了关于这个错误有多种解决的方法,但是都不是我要的,最重 ...

  7. Codeforces Round #571 (Div. 2)-D. Vus the Cossack and Numbers

    Vus the Cossack has nn real numbers aiai. It is known that the sum of all numbers is equal to 00. He ...

  8. 三层架构的一点理解以及Dapper一对多查询

    1.首先说一下自己对三层架构的一点理解 论坛里经常说会出现喜欢面相对象的写法,所以使用EF的,我个人觉得他俩没啥关系,先别反对,先听听我怎么说吧. 三层架构,基本都快说烂了,但今天还是说三层架构:UI ...

  9. 前端code导入excel

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 转:brpc的研发经历

    转载自:https://www.jianshu.com/p/124dc2c7d9d3 RPC是个老概念,五花八门的实现非常多.在14年我刚转到基础架构部时,其实是不想做RPC框架的.我的想法可能和很多 ...