zeroc ICE 使用案例

此处案例将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 });
        }
    }
View Code
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;
            }
        }
    }
View Code

 

以下为测试代码

// 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);
        }
    }
View Code
    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);
        }
    }
View Code

 

转载于:https://www.cnblogs.com/hahanonym/p/11178329.html

zero ICE快速入门文档, ice是最优秀的rpc框架。 4、开发服务端代码如下 步骤一:编写Servant类即带有Disp的存根文件也就是说继承_HelloWorldDisp 这个类,这个类是个抽象类定义如下: public abstract class _HelloWorldDisp extends Ice.ObjectImpl implements HelloWorld{} servant类是ice所定义的接口,在服务器端的实现类。我们在该类中可以编写服务器端对请求的具体处理。 代码如下: package myHelloWorld.server; import Ice.Current; import myHelloWorld._HelloWorldDisp; public class HelloWorld_gaojs extends _HelloWorldDisp{ private static final long serialVersionUID = 1L; public void say(String s, Current __current) { System.out.println("Hello World!"+" the string s is " + s); } } 步骤二:创建远程的服务器类 package myHelloWorld.server; public class ServerStart { /** * @param args */ public static void main(String[] args) { int status = 0; // Communicator实例,是ice run time的主句柄 Ice.Communicator ic = null; try { // 调用Ice.Util.Initialize()初始化Ice run time System.out.println("初始化ice run time..."); ic = Ice.Util.initialize(args); // args参数可传可不传 // 创建一个对象适配器,传入适配器名字和在10000端口处接收来的请求 System.out.println("创建对象适配器,监听端口10000..."); Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints( "SimplePrinterAdapter", "default -p 10000"); // 实例化一个PrinterI对象,为Printer接口创建一个servant System.out.println("为接口创建servant..."); Ice.Object object = new HelloWorld_gaojs(); // 调用适配器的add,告诉它有一个新的servant,传递的参数是刚才的servant,这里的“gaojs”是Servant的名字 System.out.println("对象适配器加入servant..."); adapter.add(object, Ice.Util.stringToIdentity("gaojs")); // 调用适配器的activate()方法,激活适配器。被激活后,服务器开始处理来自客户的请求。 System.out.println("激活适配器,服务器等待处理请求..."); adapter.activate(); // 这个方法挂起发出调用的线程,直到服务器实现终止为止。或我们自己发出一个调用关闭。 ic.waitForShutdown(); } catch (Ice.LocalException e) { e.printStackTrace(); status = 1; } catch (Exception e) { e.printStackTrace(); status = 1; } finally { if (ic != null) { ic.destroy(); } } System.exit(status); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值