The Internet Communications Engine (Ice) 跨平台异构通讯方案 第二弹-Hello world!
如果不知道ICE是什么的同学,请看上一篇的ICE简介:http://www.cnblogs.com/winds/p/3864677.html
好了,HelloWorld,从中间语言讲起。
首先,我们新建一个控制台项目,添加一个txt文件,在其中写上中间语言代码:
#ifndef HELLO_ICE #define HELLO_ICE module Demo { interface Hello { void sayHello(int delay); void shutdown(); }; }; #endif
这是一段很简单的代码,其中
#ifndef HELLO_ICE #define HELLO_ICE #endif
这是ICE的一个的规范而已,必须要加,否则接下来的编译器会通不过。这个语法和.Net的条件编译不一样,更多的像C中的代码风格。
module Demo
{
}
对应的是.net中的命名空间
interface Hello { void sayHello(int delay); void shutdown(); };
这个是一个简单的接口。简单的介绍完后,接下来的我们把txt后缀改为.ice后缀。
接下来,右键项目:
将EnableBuilder勾上,接下来ICE会自动帮我们生成Hello.cs文件:
好了,这个Hello.cs文件有我们定义好的被编译为C#的接口,接下里我们开始让服务端实现接口:
public class HelloI : HelloDisp_ { public override void sayHello(int delay, Ice.Current current) { if(delay > 0) { System.Threading.Thread.Sleep(delay); } System.Console.Out.WriteLine("Hello World!"); } public override void shutdown(Ice.Current current) { System.Console.Out.WriteLine("Shutting down..."); current.adapter.getCommunicator().shutdown(); } }
其中HelloDisp_为Hello.cs文件中被编译为C#了的一个抽象类,我们实现接口,接下来,我们了解一下ICE的基本配置(好吧,又是配置),不过这个配置比起WCF简单多了:
Hello.Endpoints=tcp -p 10000:udp -p 10000
当然我们要新建一个配置文件,名字可以随便取。这里我取的名字为:config.server 放在项目的根目录下:
接下来,写服务端:
public class Server { class App : Ice.Application { public override int run(string[] args) { if(args.Length > 0) { System.Console.Error.WriteLine(appName() + ": too many arguments"); return 1; } Ice.ObjectAdapter adapter = communicator().createObjectAdapter("Hello"); adapter.add(new HelloI(), communicator().stringToIdentity("hello")); adapter.activate(); communicator().waitForShutdown(); return 0; } } public static int Main(string[] args) { App app = new App(); app.main(args, "config.server");return 1; } }
OK了,服务端写完了,接下来写客户端:
public class Client { public class App : Ice.Application { private static void menu() { Console.Write( "usage:\n" + "t: send greeting as twoway\n" + "o: send greeting as oneway\n" + "O: send greeting as batch oneway\n" + "d: send greeting as datagram\n" + "D: send greeting as batch datagram\n" + "f: flush all batch requests\n" + "T: set a timeout\n" + "P: set a server delay"); if(_haveSSL) { Console.Write("\nS: switch secure mode on/off"); } Console.WriteLine( "\ns: shutdown server\n" + "x: exit\n" + "?: help\n"); } public override int run(string[] args) { if(args.Length > 0) { Console.Error.WriteLine(appName() + ": too many arguments"); return 1; } try { communicator().getPluginManager().getPlugin("IceSSL"); _haveSSL = true; } catch(Ice.NotRegisteredException) { } HelloPrx twoway = HelloPrxHelper.checkedCast( communicator().propertyToProxy("Hello.Proxy").ice_twoway().ice_timeout(-1).ice_secure(false)); if(twoway == null) { Console.Error.WriteLine("invalid proxy"); return 1; } HelloPrx oneway = (HelloPrx)twoway.ice_oneway(); HelloPrx batchOneway = (HelloPrx)twoway.ice_batchOneway(); HelloPrx datagram = (HelloPrx)twoway.ice_datagram(); HelloPrx batchDatagram =(HelloPrx)twoway.ice_batchDatagram(); bool secure = false; int timeout = -1; int delay = 0; menu(); string line = null; do { try { Console.Out.Write("==> "); Console.Out.Flush(); line = Console.In.ReadLine(); if(line == null) { break; } if(line.Equals("t")) { twoway.sayHello(delay); } else if(line.Equals("o")) { oneway.sayHello(delay); } else if(line.Equals("O")) { batchOneway.sayHello(delay); } else if(line.Equals("d")) { if(secure) { Console.WriteLine("secure datagrams are not supported"); } else { datagram.sayHello(delay); } } else if(line.Equals("D")) { if(secure) { Console.WriteLine("secure datagrams are not supported"); } else { batchDatagram.sayHello(delay); } } else if(line.Equals("f")) { communicator().flushBatchRequests(); } else if(line.Equals("T")) { if(timeout == -1) { timeout = 2000; } else { timeout = -1; } twoway = (HelloPrx)twoway.ice_timeout(timeout); oneway = (HelloPrx)oneway.ice_timeout(timeout); batchOneway = (HelloPrx)batchOneway.ice_timeout(timeout); if(timeout == -1) { Console.WriteLine("timeout is now switched off"); } else { Console.WriteLine("timeout is now set to 2000ms"); } } else if(line.Equals("P")) { if(delay == 0) { delay = 2500; } else { delay = 0; } if(delay == 0) { Console.WriteLine("server delay is now deactivated"); } else { Console.WriteLine("server delay is now set to 2500ms"); } } else if(_haveSSL && line.Equals("S")) { secure = !secure; twoway = (HelloPrx)twoway.ice_secure(secure); oneway = (HelloPrx)oneway.ice_secure(secure); batchOneway = (HelloPrx)batchOneway.ice_secure(secure); datagram = (HelloPrx)datagram.ice_secure(secure); batchDatagram = (HelloPrx)batchDatagram.ice_secure(secure); if(secure) { Console.WriteLine("secure mode is now on"); } else { Console.WriteLine("secure mode is now off"); } } else if(line.Equals("s")) { twoway.shutdown(); } else if(line.Equals("x")) { // Nothing to do } else if(line.Equals("?")) { menu(); } else { Console.WriteLine("unknown command `" + line + "'"); menu(); } } catch(System.Exception ex) { Console.Error.WriteLine(ex); } } while (!line.Equals("x")); return 0; } private static bool _haveSSL = false; } public static int Main(string[] args) { App app = new App(); return app.main(args, "config.client"); } }
从这个客户端明眼人应该能看出不少东西,以后再依此介绍。当然客户端文件配置:
Hello.Proxy=hello:tcp -p 10000:udp -p 10000 Ice.Default.Host=192.168.1.103
好了,启动服务端和运行客户端,效果如下:
Hello world完成。源码奉上:https://files.cnblogs.com/winds/hello.zip