nio socket 及其开源框架MINA学习总结(二)
2007-12-14 17:23
411 查看
关键字: nio socket MINA
3:Socket网络框架 MINA MINA是一个网络应用框架,在不牺牲性能和可扩展性的前提下用于解决如下问题: 1:快速开发自己的英勇。 2:高可维护性,高可复用性:网络I/O编码,消息的编/解码,业务逻辑互相分离。 3:相对容易的进行单元测试。 3.1 IoFilters: IoFilter为MINA的功能扩展提供了接口。它拦截所有的IO事件进行事件的预处理和后处理(AOP)。我们可以把它想象成 Servlet的filters。 IoFilter能够实现以下几种目的: 事件日志 性能检测 数据转换(e.g. SSL support),codec 防火墙…等等 3.2 codec: ProtocolCodecFactory MINA提供了方便的Protocol支持。如上说讲,codec在IoFilters中设置。 通过它的Encoder和Decoder,可以方便的扩展并支持各种基于Socket的网络协议,比如HTTP服务器、FTP服务器、Telnet服务器等等。 要实现自己的编码/解码器(codec)只需要实现interface: ProtocolCodecFactory即可. 在MINA 1.0版本,MINA已经实现了几个常用的(codec factory): DemuxingProtocolCodecFactory, NettyCodecFactory, ObjectSerializationCodecFactory, TextLineCodecFactory 其中: TextLineCodecFactory: A ProtocolCodecFactory that performs encoding and decoding between a text line data and a Java string object. This codec is useful especially when you work with a text-based protocols such as SMTP and IMAP. ObjectSerializationCodecFactory: A ProtocolCodecFactory that serializes and deserializes Java objects. This codec is very useful when you have to prototype your application rapidly without any specific codec. DemuxingProtocolCodecFactory: A composite ProtocolCodecFactory that consists of multiple MessageEncoders and MessageDecoders. ProtocolEncoder and ProtocolDecoder this factory returns demultiplex incoming messages and buffers to appropriate MessageEncoders and MessageDecoders. NettyCodecFactory: A MINA ProtocolCodecFactory that provides encoder and decoder for Netty2 Messages and MessageRecognizers. 3.3 business logic: IoHandler MINA中,所有的业务逻辑都有实现了IoHandler的class完成 interfaceHandles: all protocol events fired by MINA. There are 6 event handler methods, and they are all invoked by MINA automatically. 当事件发生时,将触发IoHandler中的方法: sessionCreated(), sessionOpened(), sessionClosed(), sessionIdle(), exceptionCaught(), messageReceived(), messageSent() MINA 1.O中,IoHandler的实现类: ChainedIoHandler, DemuxingIoHandler, IoHandlerAdapter, SingleSessionIoHandlerDelegate, StreamIoHandler 具体细节可参考javadoc。 3.4 MINA的高级主题:线程模式 MINA通过它灵活的filter机制来提供多种线程模型。 没有线程池过滤器被使用时MINA运行在一个单线程模式。 如果添加了一个IoThreadPoolFilter到IoAcceptor,将得到一个leader-follower模式的线程池。 如果再添加一个ProtocolThreadPoolFilter,server将有两个线程池; 一个(IoThreadPoolFilter)被用于对message对象进行转换,另外一个(ProtocolThreadPoolFilter)被用于处理业务逻辑。 SimpleServiceRegistry加上IoThreadPoolFilter和ProtocolThreadPoolFilter的缺省实现即可适用于需 要高伸缩性的应用。如果想使用自己的线程模型,请参考SimpleServiceRegistry的源代码,并且自己 初始化Acceptor。 java 代码 IoThreadPoolFilter threadPool = new IoThreadPoolFilter();threadPool.start(); IoAcceptor acceptor = new SocketAcceptor(); acceptor.getFilterChain().addLast( "threadPool", threadPool); ProtocolThreadPoolFilter threadPool2 = new ProtocolThreadPoolFilter(); threadPool2.start(); ProtocolAcceptor acceptor2 = new IoProtocolAcceptor( acceptor ); acceptor2.getFilterChain().addLast( "threadPool", threadPool2 ); ... threadPool2.stop(); threadPool.stop(); 3.5 采用MINA进行socket开发,一般步骤如下: 1: IoAcceptor acceptor = new SocketAcceptor(); //建立client接收器 or client: SocketConnector connector = new SocketConnector(); //建立一个连接器 2:server的属性配置: java 代码 SocketAcceptorConfig cfg = new SocketAcceptorConfig(); cfg.setReuseAddress(true); cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); //对象序列化 codec factory cfg.getFilterChain().addLast( "logger", new LoggingFilter() ); 3:绑定address和business logic server: java 代码 acceptor.bind( new InetSocketAddress( SERVER_PORT ), new ServerSessionHandler( ), cfg ); // 绑定address和handler connector.connect(new InetSocketAddress( HOSTNAME, PORT ), new ClientSessionHandler(msg), cfg ); 下面的这个简单的example演示client和server传递object的过程: Message.java java 代码 public class Message implements Serializable { private int type; private int status; private String msgBody; public Message(int type, int status, String msgBody) { this.type = type; this.status = status; this.msgBody = msgBody; } public String getMsgBody() { return msgBody; } public void setMsgBody(String msgBody) { this.msgBody = msgBody; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public int getType() { return type; } public void setType(int type) { this.type = type; } } Client.java java 代码 public class Client { private static final String HOSTNAME = "localhost"; private static final int PORT = 8080; private static final int CONNECT_TIMEOUT = 30; // seconds public static void main( String[] args ) throws Throwable { SocketConnector connector = new SocketConnector(); // Configure the service. SocketConnectorConfig cfg = new SocketConnectorConfig(); cfg.setConnectTimeout( CONNECT_TIMEOUT ); cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); cfg.getFilterChain().addLast( "logger", new LoggingFilter() ); IoSession session; Message msg = new Message(0,1,"hello"); connector.connect(new InetSocketAddress( HOSTNAME, PORT ), new ClientSessionHandler(msg), cfg ); } } ClientSessionHandler.java java 代码 public class ClientSessionHandler extends IoHandlerAdapter { private Object msg; public ClientSessionHandler(Object msg) { this.msg = msg; } public void sessionOpened( IoSession session ) { session.write(this.msg); } public void messageReceived( IoSession session, Object message ) { System.out.println("in messageReceived!"); Message rm = (Message ) message; SessionLog.debug(session, rm.getMsgBody()); System.out.println("message is: " + rm.getMsgBody()); session.write(rm); } public void exceptionCaught( IoSession session, Throwable cause ) { session.close(); } } Server.java java 代码 public class Server { private static final int SERVER_PORT = 8080; public static void main( String[] args ) throws Throwable { IoAcceptor acceptor = new SocketAcceptor(); // Prepare the service configuration. SocketAcceptorConfig cfg = new SocketAcceptorConfig(); cfg.setReuseAddress( true ); cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) ); cfg.getFilterChain().addLast( "logger", new LoggingFilter() ); acceptor.bind( new InetSocketAddress( SERVER_PORT ), new ServerSessionHandler( ), cfg ); System.out.println( "The server Listening on port " + SERVER_PORT ); } } ServerSessionHandler.java java 代码 public class ServerSessionHandler extends IoHandlerAdapter { public void sessionOpened( IoSession session ) { // set idle time to 60 seconds session.setIdleTime( IdleStatus.BOTH_IDLE, 60 ); session.setAttribute("times",new Integer(0)); } public void messageReceived( IoSession session, Object message ) { System.out.println("in messageReceived"); int times = ((Integer)(session.getAttribute("times"))).intValue(); System.out.println("tiems = " + times); // communicate 30 times,then close the session. if (times < 30) { times++; session.setAttribute("times", new Integer(times)); Message msg; msg = (Message) message; msg.setMsgBody("in server side: " + msg.getMsgBody()); System.out.println("begin send msg: " + msg.getMsgBody()); session.write(msg); } else { session.close(); } } public void sessionIdle( IoSession session, IdleStatus status ) { SessionLog.info( session, "Disconnecting the idle." ); // disconnect an idle client session.close(); } public void exceptionCaught( IoSession session, Throwable cause ) { // close the connection on exceptional situation session.close(); } } MINA自己附带的Demo已经很好的说明了它的运用。 值得一提的是它的SumUp:客户端发送几个数字,服务端求和后并返回结果。这个简单的程序演示了如何自己实现CODEC。 补充提示: 下载并运行MINA的demo程序还颇非周折: 运行MINA demo appli擦tion: 1:在JDK5 产生错误: Exception in thread "main" java.lang.NoClassDefFoundError: edu/emory/mathcs/backport/java/util/concurrent/Executor at org.apache.mina.example.reverser.Main.main(Main.java:44) 察看mina的QA email: http://www.mail-archive.com/mina-dev@directory.apache.org/msg02252.html 原来需要下载:backport-util-concurrent.jar并加入classpath http://dcl.mathcs.emory.edu/util/backport-util-concurrent 继续运行还是报错: Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory 原来MINA采用了slf4j项目作为log,继续下载 slf4j-simple.jar等,并加入classpath: http://www.slf4j.org/download.html 附件是mina demo的eclipse工程。导入就可运行,所有的相关jar包在bin目录下 |
相关文章推荐
- nio socket 及其开源框架MINA学习总结
- nio socket 及其开源框架MINA学习总结(一)
- nio socket 及其开源框架MINA学习总结(二)
- nio socket 及其开源框架MINA学习总结(一)
- nio socket 及其开源框架MINA学习总结(二)
- nio socket 及其开源框架MINA学习总结(一)
- socket, nio socket 及nio socket框架MINA总结 (转)
- 常见NIO开源框架(MINA、xSocket)学习
- iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇
- android(安卓)开源框架学习总结
- socket, nio socket 及nio socket框架MINA总结
- Android二维码ZXing开源框架的学习总结
- hadoop 分布式计算开源框架 学习总结
- socket, nio socket 及nio socket框架MINA总结 (转)
- socket, nio socket 及nio socket框架MINA总结
- 开源搜索框架Lucene学习之分词器(2)——TokenFilter类及其子类
- socket, nio socket 及nio socket框架MINA总结
- iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇
- 学习开源框架WebX的总结