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

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

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

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

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

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

4、双向自由互调。

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

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

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

需要改进重连机制

  1. public class ICEClient<T,TPrx>
  2. {
  3. public TPrx Server { get; private set; }
  4.  
  5. public bool Online { get; private set; }
  6.  
  7. ILog _Logger = Spv2LoggerFactory.GetLoggerByName("RPC");
  8.  
  9. string _IPAddress;
  10. int _Port;
  11. int connectTimeout = 60000;
  12. int idleTimeout = -1; //no limit
  13.  
  14. public ICEClient(string ip, int port)
  15. {
  16. _IPAddress = ip;
  17. _Port = port;
  18. }
  19.  
  20. /// <summary>
  21. ///
  22. /// </summary>
  23. /// <param name="Servant"> 作为服务端接收指令响应</param>
  24. public void Connect(T Servant=default(T))
  25. {
  26. if (Online)
  27. {
  28. _Logger.InfoFormat("Initializing, Online!");
  29. return;
  30. }
  31. try
  32. {
  33. _Logger.InfoFormat("Initializing ICE Comm using Host: {0}, Port: {1}, connectTimeout: {2}, idleTimeout: {3}",
  34. _IPAddress, _Port, connectTimeout, idleTimeout);
  35.  
  36. // TODO figure out how to use properties.
  37. Ice.InitializationData id = new Ice.InitializationData();
  38. id.properties = Ice.Util.createProperties();
  39. id.properties.setProperty("Ice.Default.ConnectTimeout", connectTimeout.ToString());
  40. id.properties.setProperty("Ice.Default.Timeout", idleTimeout.ToString()); // 5 min?
  41. id.properties.setProperty("Ice.Warn.UnusedProperties", "1");
  42. id.properties.setProperty("Ice.Warn.Host", _IPAddress);
  43.  
  44. var _ICEComm = Ice.Util.initialize(id);
  45.  
  46. string connectString = String.Format("{0}:tcp -p {1} -h {2}", typeof(T).Name, _Port, _IPAddress);
  47. ObjectPrx iceProxy = _ICEComm.stringToProxy(connectString);
  48.  
  49. Server = CreateServerProxy(iceProxy);
  50.  
  51. _Logger.InfoFormat("ICE check proxy cast finished. {0}", _IPAddress);
  52. if (Server == null)
  53. {
  54. _ICEComm.destroy();
  55. _ICEComm = null;
  56. id = null;
  57. GC.Collect();
  58. throw new System.Exception("Invalid proxy");
  59. }
  60.  
  61. if(Servant!=null)
  62. {
  63. Ice.ObjectAdapter iceAdapter = _ICEComm.createObjectAdapter("");
  64. iceAdapter.add((Ice.Object)Servant, iceProxy.ice_getIdentity());
  65. iceProxy.ice_getConnection().setAdapter(iceAdapter);
  66. iceAdapter.activate();
  67. }
  68. }
  69. catch (System.Exception ex)
  70. {
  71. Online = false;
  72. GC.Collect();
  73. string errorMsg = String.Format("System Exception {0} caught.", ex.Message);
  74. _Logger.Error(errorMsg);
  75. throw;
  76. }
  77. Online = true;
  78. }
  79.  
  80. private TPrx CreateServerProxy(ObjectPrx iceProxy)
  81. {
  82. //TestICEPrxHelper
  83. var str = typeof(TPrx).FullName + "Helper";
  84. var type = Type.GetType(str);
  85. var serverproxy = Activator.CreateInstance(type);
  86.  
  87. //static method
  88. var method = type.GetRuntimeMethod("uncheckedCast", new Type[] { typeof(ObjectPrx) });
  89.  
  90. return (TPrx)method.Invoke(type, new[] { iceProxy });
  91. }
  92. }
  1. public class ICEServer<T,TPrx>
  2. {
  3. ILog _Logger = Spv2LoggerFactory.GetLoggerByName("RPC");
  4.  
  5. /// <summary>
  6. /// 客户端的集合
  7. /// </summary>
  8. public Dictionary<string,TPrx> Clients { get; set; } = new Dictionary<string, TPrx>();
  9.  
  10. string _IPAddress;
  11. int _Port;
  12.  
  13. public ICEServer(string ip, int port)
  14. {
  15. _IPAddress = ip;
  16. _Port = port;
  17. }
  18.  
  19. /// <summary>
  20. ///
  21. /// </summary>
  22. /// <param name="Servant"> 作为服务端接收指令响应</param>
  23. public void StartUp(T Servant)
  24. {
  25. try
  26. {
  27. _Logger.InfoFormat("Initializing ICE Comm using Host: {0}, Port: {1}",_IPAddress, _Port);
  28.  
  29. var _ICEComm = Ice.Util.initialize();
  30. Ice.Communicator iceComm = Ice.Util.initialize();
  31. // Create adaptor for commands and requests from client
  32.  
  33. Ice.ObjectAdapter iceAdapter = iceComm.createObjectAdapterWithEndpoints(typeof(T).Name, $"tcp -p {_Port} -h {_IPAddress}");
  34. iceAdapter.add((Ice.Object)Servant, iceComm.stringToIdentity(typeof(T).Name));
  35. iceAdapter.activate();
  36. }
  37. catch (System.Exception ex)
  38. {
  39. GC.Collect();
  40. string errorMsg = String.Format("System Exception {0} caught.", ex.Message);
  41. _Logger.Error(errorMsg);
  42. throw;
  43. }
  44. }
  45. }

以下为测试代码

  1. // Copyright 2016 Complete Genomics, Inc. All Rights Reserved.
  2. // Confidential and proprietary works of Complete Genomics, Inc.
  3.  
  4. module My {
  5. module RPC {
  6. interface TestICE
  7. {
  8. void AddClient(string name);
  9.  
  10. string ClientCallServer(int i);
  11.  
  12. void ServerCallClient(int i);
  13. };
  14. };
  15. };
  1. internal class TestICEServer : TestICEDisp_
  2. {
  3. ICEServer<TestICE, TestICEPrx> server;
  4. internal TestICEServer()
  5. {
  6. server = new ICEServer<TestICE, TestICEPrx>("172.16.35.66", 11106);
  7. server.StartUp(this);
  8. }
  9. public override void AddClient(string name, Current current__)
  10. {
  11. Ice.ObjectPrx @base = current__.con.createProxy(current__.id);
  12. var client = TestICEPrxHelper.checkedCast(@base);
  13. server.Clients.Add(name, client);
  14. }
  15.  
  16. public override string ClientCallServer(int i, Current current__)
  17. {
  18. return (++i).ToString();
  19. }
  20.  
  21. public override void ServerCallClient(int i, Current current__)
  22. {
  23. foreach (var client in server.Clients.Values)
  24. {
  25. client.ServerCallClient(i);
  26. }
  27. }
  28. }
  29.  
  30. public class TestServerService : TestICEOperationsNC_
  31. {
  32. TestICEServer server;
  33. public TestServerService()
  34. {
  35. server = new TestICEServer();
  36. }
  37.  
  38. public void AddClient(string name)
  39. {
  40. server.AddClient(name);
  41. }
  42.  
  43. public string ClientCallServer(int i)
  44. {
  45. return server.ClientCallServer(i);
  46. }
  47.  
  48. public void ServerCallClient(int i)
  49. {
  50. server.ServerCallClient(i);
  51. }
  52. }
  1. internal class TestICEClient : TestICEDisp_
  2. {
  3. ICEClient<TestICE, TestICEPrx> client;
  4. internal TestICEClient()
  5. {
  6. client = new ICEClient<TestICE, TestICEPrx>("172.16.35.66", 11106);
  7. client.Connect(this);
  8. }
  9. public override void AddClient(string name, Current current__)
  10. {
  11. client.Server.AddClient(name);
  12. }
  13.  
  14. public override string ClientCallServer(int i, Current current__)
  15. {
  16. var r= client.Server.ClientCallServer(i);
  17. return r;
  18. }
  19.  
  20. public override void ServerCallClient(int i, Current current__)
  21. {
  22. var r = i;
  23. }
  24. }
  25.  
  26. public class TestICEClientService : TestICEOperationsNC_
  27. {
  28. TestICEClient server;
  29. public TestICEClientService()
  30. {
  31. server = new TestICEClient();
  32. }
  33.  
  34. public void AddClient(string name)
  35. {
  36. server.AddClient(name);
  37. }
  38.  
  39. public string ClientCallServer(int i)
  40. {
  41. return server.ClientCallServer(i);
  42. }
  43.  
  44. public void ServerCallClient(int i)
  45. {
  46. server.ServerCallClient(i);
  47. }
  48. }

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. ZooKeeper的十二连问,你顶得了嘛?

    前言 一线大厂ZooKeeper的十二连问,你顶得了嘛? 本文已经收录到github ❝ https://github.com/whx123/JavaHome ❞ 1. 面试官:工作中使用过Zooke ...

  2. ES5和ES6的继承对比

    ES5的继承实现,这里以最佳实践:寄生组合式继承方式来实现.(为什么是最佳实践,前面有随笔讲过了,可以参考) function Super(name) { this.name = name; } Su ...

  3. nginx如何限制并发连接请求数?

    简介 限制并发连接数的模块为:http_limit_conn_module,地址:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.ht ...

  4. vue mixin混入

    基本结构 export default { data() { return {} }, computed: { }, methods: { }, filters: { }, created() { } ...

  5. PHP 安装 扩展时 抛出 /usr/local/Cellar/php@7.1/7.1.25/pecl 异常解决

    liugx@MacBook-Pro  ~/work/php/ext_source/php-xhprof-extension   master  make installmkdir: /usr/ ...

  6. i春秋公益赛之signin

    题目链接:https://buuoj.cn/challenges#gyctf_2020_signin 查看程序保护 只开了canary和NX保护,在IDA查看反编译出来的为代码时发现程序给了一个后门 ...

  7. Vue cli4 图片地址引入的几种方式

    五种图片地址引入方式 @开头,它也会作为一个模块请求被解析.它的用处在于Vue CLI默认会设置一个指向项目根目录/src的别名@

  8. 工具-Typora常用语法()+自己总结

    工具-Typora常用语法 Markdown(MD)作为目前互联网写作相当流行的一种文档撰写语言格式,深受互联网编辑者的喜爱,由此周边一些基于MD的编辑工具也随之油然而生. 作为一款免费的MD编辑器: ...

  9. [LeetCode]404. 左叶子之和(递归)、938. 二叉搜索树的范围和(递归)(BST)

    题目 404. 左叶子之和 如题 题解 类似树的遍历的递归 注意一定要是叶子结点 代码 class Solution { public int sumOfLeftLeaves(TreeNode roo ...

  10. 学习 | css3实现进度条加载

    进度条加载是页面加载时的一种交互效果,这样做的目的是提高用户体验. 进度条的的实现分为3大部分:1.页面布局,2.进度条动效,3.何时进度条增加. 文件目录 加载文件顺序 <link rel=& ...