Apache Mina是一個能夠幫助用戶開發(fā)高性能和高伸縮性網(wǎng)絡應用程序的框架。它通過Java nio技術基于TCP/IP和UDP/IP協(xié)議提供了抽象的、事件驅動的、異步的API。 Mina包的簡介:
先介紹Mina幾個重要接口:
MIINA架構圖 在圖中的模塊鏈中,IoService 便是應用程序的入口,相當于我們前面代碼中的 IoAccepter,IoAccepter 便是 IoService 的一個擴展接口。IoService 接口可以用來添加多個 IoFilter,這些 IoFilter 符合責任鏈模式并由 IoProcessor 線程負責調用。而 IoAccepter 在 ioService 接口的基礎上還提供綁定某個通訊端口以及取消綁定的接口。 IoAcceptor acceptor = new SocketAcceptor();
上面代碼中,相當于我們使用了 Socket 通訊方式作為服務的接入,當前版本的 MINA 還提供了除 SocketAccepter 外的基于數(shù)據(jù)報文通訊的 DatagramAccepter 以及基于管道通訊的 VmPipeAccepter。另外還包括串口通訊接入方式,目前基于串口通訊的接入方式已經(jīng)在最新測試版的 MINA 中提供。你也可以自行實現(xiàn) IoService 接口來使用自己的通訊方式。 而在上圖中最右端也就是 IoHandler,這便是業(yè)務處理模塊。在業(yè)務處理類中不需要去關心實際的通訊細節(jié),只管處理客戶端傳輸過來的信息即可。編寫 Handler 類就是使用 MINA 開發(fā)網(wǎng)絡應用程序的重心所在,相當于 MINA 已經(jīng)幫你處理了所有的通訊方面的細節(jié)問題。為了簡化 Handler 類,MINA 提供了 IoHandlerAdapter 類,此類僅僅是實現(xiàn)了 IoHandler 接口,但并不做任何處理。 一個 IoHandler 接口中具有如下一些方法(摘自 MINA 的 API 文檔):
前面我們提到 IoService 是負責底層通訊接入,而 IoHandler 是負責業(yè)務處理的。那么 MINA 架構圖中的 IoFilter 作何用途呢?答案是你想作何用途都可以。但是有一個用途卻是必須的,那就是作為 IoService 和 IoHandler 之間的橋梁。IoHandler 接口中最重要的一個方法是 messageReceived,這個方法的第二個參數(shù)是一個 Object 型的消息,總所周知,Object 是所有 Java 對象的基礎,那到底誰來決定這個消息到底是什么類型呢?答案也就在這個 IoFilter 中。在前面使用的例子中,我們添加了一個 IoFilter 是 new ProtocolCodecFilter(new TextLineCodecFactory()),這個過濾器的作用是將來自客戶端輸入的信息轉換成一行行的文本后傳遞給 IoHandler,因此我們可以在 messageReceived 中直接將 msg 對象強制轉換成 String 對象。 而如果我們不提供任何過濾器的話,那么在 messageReceived 方法中的第二個參數(shù)類型就是一個 byte 的緩沖區(qū),對應的類是 org.apache.mina.core.buffer.IoBuffer。雖然你也可以將解析客戶端信息放在 IoHandler 中來做,但這并不是推薦的做法,使原來清晰的模型又模糊起來,變得 IoHandler 不只是業(yè)務處理,還得充當協(xié)議解析的任務。 MINA自身帶有一些常用的過濾器,例如LoggingFilter(日志記錄)、BlackListFilter(黑名單過濾)、CompressionFilter(壓縮)、SSLFilter(SSL加密)等。
簡單地來講,就分為三層:
客戶端的通信過程:
IoFilterChain作為消息過濾鏈
客戶端通信過程 IoSession貫穿整個通信過程的始終 創(chuàng)建服務器 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaTimeServer { // 定義監(jiān)聽端口 private static final int PORT = 6488; public static void main(String[] args) throws IOException { // 創(chuàng)建服務端監(jiān)控線程 IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getSessionConfig().setReadBufferSize(2048); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); // 設置日志記錄器 acceptor.getFilterChain().addLast("logger", new LoggingFilter()); // 設置編碼過濾器 acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); // 指定業(yè)務邏輯處理器 acceptor.setHandler(new TimeServerHandler()); // 設置端口號 acceptor.bind(new InetSocketAddress(PORT)); // 啟動監(jiān)聽線程 acceptor.bind(); } } import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; /** * 服務器端業(yè)務邏輯 */ public class TimeServerHandler extends IoHandlerAdapter { /** * 連接創(chuàng)建事件 */ @Override public void sessionCreated(IoSession session){ // 顯示客戶端的ip和端口 System.out.println(session.getRemoteAddress().toString()); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); } /** * 消息接收事件 */ @Override public void messageReceived(IoSession session, Object message) throws Exception { String strMsg = message.toString(); if (strMsg.trim().equalsIgnoreCase("quit")) { session.close(true); return; } // 返回消息字符串 session.write("Hi Client!"); // 打印客戶端傳來的消息內(nèi)容 System.out.println("Message written : " + strMsg); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("IDLE" + session.getIdleCount(status)); } } 客戶端 import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class MinaTimeClient { public static void main(String[] args){ // 創(chuàng)建客戶端連接器. NioSocketConnector connector = new NioSocketConnector(); connector.getFilterChain().addLast("logger", new LoggingFilter()); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); // 設置連接超時檢查時間 connector.setConnectTimeoutCheckInterval(30); connector.setHandler(new TimeClientHandler()); // 建立連接 ConnectFuture cf = connector.connect(new InetSocketAddress("192.168.2.109", 6488)); // 等待連接創(chuàng)建完成 cf.awaitUninterruptibly(); cf.getSession().write("Hi Server!"); cf.getSession().write("quit"); // 等待連接斷開 cf.getSession().getCloseFuture().awaitUninterruptibly(); // 釋放連接 connector.dispose(); } } import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; public class TimeClientHandler extends IoHandlerAdapter { public void messageReceived(IoSession session, Object message) throws Exception { String content = message.toString(); System.out.println("client receive a message is : " + content); } public void messageSent(IoSession session, Object message) throws Exception { System.out.println("messageSent -> :" + message); } }
http://my.oschina.net/ielts0909/blog?catalog=253154 http://www./mikechen/archive/2012/03/15/371938.html http://dxf1122.blog.163.com/blog/static/54041004200931371414356/ http://blog.sina.com.cn/s/blog_7abc61de0100sdoi.html http://mina./mina-project/documentation.html http://wenku.baidu.com/view/b9af67c34028915f804dc292.html http://wenku.baidu.com/view/46800bce0508763231121232.html http://wenku.baidu.com/view/5ccc7935b90d6c85ec3ac6e7.html
|
|