设为首页 收藏本站
查看: 579|回复: 0

[经验分享] Apache MINA 快速入门指南

[复制链接]

尚未签到

发表于 2016-12-31 12:04:57 | 显示全部楼层 |阅读模式
  from: http://tianting-wx.iteye.com/blog/265539  
  “MINA是一个Socket的网络框架,但是它提供了方便的Protocol支持,通过它的Encoder和Decoder,你将你的应用可以方便的扩展并支持各种基于Socket的网络协议,比如HTTP服务器、FTP服务器(当然,这很复杂)、Telnet服务器等等。基于MINA用户可以容易地开发高性能和高伸缩性的网络应用程序。”
  下面是对官方入门文档的中文译版,由于完全参照官方文档在程序具体运行时遇到一些import不足的情况,在示例源码的import是我在亲自实践后修改过的,其他的地方都和原文一样。
  Apache MINA 快速入门
  Added by Mark Webb, last edited by Trustin Lee on Apr 16, 2007    (view change)
  1    简介
  
  建立一个基于MINA的时间服务器,下面的内容需要先准备好。
  1,Mina 1.1 Core
2,JDK 1.5 or greater
3,SLF4J 1.3.0 or greater :
   Log4J 1.2 users: slf4j-api.jar, slf4j-log4j12.jar, and Log4J 1.2.x
   Log4J 1.3 users: slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.x
   java.util.logging users: slf4j-api.jar and slf4j-jdk14.jar
  
   注意:首先请确认你使用了正确的slf4j-*.jar 。比如说slf4j-log4j12.jar 和log4j-1.3.x.jar 是不能在一起使用的将会出现功能障碍。
  
 (我用了1.2系列,那么所有的软件包就是:
 log4j-1.2.14.jar;
 mina-core-1.1.2.jar;
 slf4j-api-1.2.jar;
 slf4j-jdk14-1.2.jar;
 slf4j-log4j12-1.2.jar)
  这个程序只测试了Windows2000pro 和 Linux系统,并且在做的时候没有依赖于一些开发平台的环境。
  2    编写MINA时间服务
  下面先建立一个文件MinaTimeServer.java,代码如下:

Java代码 DSC0000.gif   DSC0001.png DSC0002.gif





  • public class MinaTimeServer {  
  •     public static void main(String[] args) {  
  •       // code will go here next  
  •     }  
  • }  



public class MinaTimeServer {
public static void main(String[] args) {
// code will go here next
}
}

  下面会慢慢将这个类写完,这里定义一个main用于启动程序。这一步结束后,还需要一个监听连接的对象,因为这个程序是基于TCP/IP的,这里将增加一个SocketAcceptor。

Java代码  





  • import org.apache.mina.common.IoAcceptor;  
  • import org.apache.mina.transport.socket.nio.SocketAcceptor;  
  •   
  • public class MinaTimeServer {  
  •     public static void main(String[] args) {  
  •       // The following two lines change the default buffer type to 'heap',  
  •       // which yields better performance.  
  •       ByteBuffer.setUseDirectBuffers(false);  
  •       ByteBuffer.setAllocator(new SimpleByteBufferAllocator());  
  •       IoAcceptor acceptor = new SocketAcceptor();  
  •     }  
  • }  



import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
public class MinaTimeServer {
public static void main(String[] args) {
// The following two lines change the default buffer type to 'heap',
// which yields better performance.
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
}
}

  通过这里的SocketAcceptor类,下面将把它绑定到一个端口上,如果你想增加一个线程模型到该类的话,参考"配置线程模型"部分。
  现在我们为SocketAcceptor添加设置。它允许我们为Socekt配置明确套接字用于允许来自客户端的连接。
    

Java代码  





  • import java.io.IOException;  
  • import java.net.InetSocketAddress;  
  • import org.apache.mina.common.IoAcceptor;  
  • import org.apache.mina.transport.socket.nio.SocketAcceptor;  
  •   
  • public class MinaTimeServer {  
  •   
  •     private static final int PORT = 9123;  
  •   
  •     public static void main(String[] args) throws IOException {  
  •         ByteBuffer.setUseDirectBuffers(false);  
  •         ByteBuffer.setAllocator(new SimpleByteBufferAllocator());  
  •   
  •         IoAcceptor acceptor = new SocketAcceptor();  
  •   
  •         SocketAcceptorConfig cfg = new SocketAcceptorConfig();  
  •         cfg.getSessionConfig().setReuseAddress( true );  
  •         cfg.getFilterChain().addLast( "logger"new LoggingFilter() );  
  •         cfg.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));  
  •   
  •     }  
  • }  



import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
public class MinaTimeServer {
private static final int PORT = 9123;
public static void main(String[] args) throws IOException {
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.getSessionConfig().setReuseAddress( true );
cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
}
}


  SocketAcceptorConfig类的实例用于当我们每次准备启动acceptor的时候进入这个acceptor。
  
    首先,我们设置一个重用地址标识。从 JDK Documentation可以了解更多关于这里的知识。
  然后我们在配置中添加一个过滤器。这个过滤器filter将记录所有信息,例如最近创建的sessions,收到的消息,发送
  的消息,session关闭。
  下一个过滤器是一个ProtocolCodecFilter。这个过滤器可以将二进制数据或编码协议数据转换成消息对象和代替法。
  下面的部分来为acceptor绑定端口。这个方法标志着服务器进程的启动,如果这个方法没有被调用,服务器将不会与客户端进行连接

Java代码  





  • import java.io.IOException;  
  • import java.net.InetSocketAddress;  
  • import java.nio.charset.Charset;  
  •   
  • import org.apache.mina.common.ByteBuffer;  
  • import org.apache.mina.common.IoAcceptor;  
  • import org.apache.mina.common.SimpleByteBufferAllocator;   
  • import org.apache.mina.transport.socket.nio.SocketAcceptor;  
  • import org.apache.mina.filter.LoggingFilter;  
  • import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  • import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  • import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;  
  •   
  • public class MinaTimeServer {  
  •   
  •     private static final int PORT = 9123;  
  •   
  •     public static void main(String[] args) throws IOException {  
  •         ByteBuffer.setUseDirectBuffers(false);  
  •         ByteBuffer.setAllocator(new SimpleByteBufferAllocator());  
  •   
  •         IoAcceptor acceptor = new SocketAcceptor();  
  •   
  •         SocketAcceptorConfig cfg = new SocketAcceptorConfig();  
  •         cfg.getFilterChain().addLast( "logger"new LoggingFilter() );  
  •         cfg.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));  
  •   
  •         acceptor.bind( new InetSocketAddress(PORT), new TimeServerHandler(), cfg);  
  •         System.out.println("MINA Time server started.");  
  •     }  
  • }  



import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.SimpleByteBufferAllocator;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
public class MinaTimeServer {
private static final int PORT = 9123;
public static void main(String[] args) throws IOException {
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
acceptor.bind( new InetSocketAddress(PORT), new TimeServerHandler(), cfg);
System.out.println("MINA Time server started.");
}
}

  这里定义了一个整型的端口变量,呼叫SocketAcceptor.bind(SocketAddress,IoHandler,cfg),第一个参数是要监听的网址,是本地的9123端口
  第二个参数传的是实现IoHandler接口的类,是服务于所有的客户端请求的。在这里,将会扩展IoHandlerAdapter类,这类遵循"适配器设计模式"的。
  第三个参数是配置对象,用于配置日志和编码过滤器。每一个信息都会通过在IoAcceptor中定义的过滤器链的所有过滤器。在这风景点,将会将信息通过日志和编码过滤器。日志过滤器用SL4J库记录信息,而编码过滤器则反编码所有收到的信息,并且将所有TextLineCodecFactory发送的信息进行编码。
  下面就是TimeServerHandler类的代码: 

Java代码  





  • import java.util.Date;  
  • import org.apache.mina.common.IoHandlerAdapter;  
  • import org.apache.mina.common.IoSession;  
  •   
  • public class TimeServerHandler extends IoHandlerAdapter {  
  •   
  •     public void exceptionCaught(IoSession session, Throwable t) throws Exception {  
  •       t.printStackTrace();  
  •       session.close();  
  •     }  
  •   
  •     public void messageReceived(IoSession session, Object msg) throws Exception {  
  •       String str = msg.toString();  
  •       if( str.trim().equalsIgnoreCase("quit") ) {  
  •         session.close();  
  •         return;  
  •       }  
  •       Date date = new Date();  
  •       session.write( date.toString() );  
  •       System.out.println("Message written...");  
  •     }  
  •   
  •     public void sessionCreated(IoSession session) throws Exception {  
  •       System.out.println("Session created...");  
  •       if( session.getTransportType() == TransportType.SOCKET )  
  •         ((SocketSessionConfig) session.getConfig() ).setReceiveBufferSize( 2048 );  
  •       session.setIdleTime( IdleStatus.BOTH_IDLE, 10 );  
  •     }  
  • }  



import java.util.Date;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
public class TimeServerHandler extends IoHandlerAdapter {
public void exceptionCaught(IoSession session, Throwable t) throws Exception {
t.printStackTrace();
session.close();
}
public void messageReceived(IoSession session, Object msg) throws Exception {
String str = msg.toString();
if( str.trim().equalsIgnoreCase("quit") ) {
session.close();
return;
}
Date date = new Date();
session.write( date.toString() );
System.out.println("Message written...");
}
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
if( session.getTransportType() == TransportType.SOCKET )
((SocketSessionConfig) session.getConfig() ).setReceiveBufferSize( 2048 );
session.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
}
}

  这里用于管理信息,覆盖了exceptionCaught,messageReceived 和 sessionCreated 方法,如前所示,该类扩展了IoHandlerAdapter。
  exceptionCaught 方法将会打印错误并且关闭对话,对于大多数的情况来讲,这是标准的处理方法,除非能从异常中恢复过来。
  messageReceived 方法将收到从客户端发来的数据,并且写回当前时间。如果收到了"quit",对话将被关闭。该方法将当前时间发往客户端,依赖于你使用的协议编码,发送至方法的对象(第二个参数)会有不同,发送到session.write(Object)方法的对象类同。如果你没有指定协议编码,则一般会收到ByteBuffer对象,而发送的也要是ByteBuffer对象。
  sessionCreated 方法用于对话初始化,在这里,先打印一条信息,然后判断对话的类型,再设置缓冲大小,这里设置的是2048个字节。空闲时间设置为10秒,如果覆盖了sessionIdle方法,则该方法每10秒被呼叫一次。
  3    测试
  到这里,编译程序。如果成功,那么启动程序,登陆telnet访问程序,如下所示:
  客户端内容:
user@myhost:~> telnet 127.0.0.1 9123
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello
Mon Apr 09 23:42:55 EDT 2007
quit
Connection closed by foreign host.
  
user@myhost:~>
  服务端内容:
MINA Time server started.
Session created...
Message written...
  4 参考文档
  Apache MINA Quick Start Guidehttp://mina.apache.org/documentation.html
  Added by Mark Webb, last edited by Trustin Lee on Apr 16, 2007    (view change)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-322047-1-1.html 上篇帖子: Apache和PHP的配置 下篇帖子: Apache,Resin,JVM 状态监控
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表