JavaMina-2.0.16框架學習使用

凌浩雨發表於2017-08-28

本文使用mina-2.0.16.jar

Apache Mina Server 是一個網路通訊應用框架,也就是說,它主要是對基於TCP/IP、UDP/IP協議棧的通訊框架(當然,也可以提供JAVA 物件的序列化服務、虛擬機器管道通訊服務等),Mina 可以幫助我們快速開發高效能、高擴充套件性的網路通訊應用,Mina 提供了事件驅動、非同步(Mina 的非同步IO 預設使用的是JAVA NIO 作為底層支援)操作的程式設計模型。
Mina 同時提供了網路通訊的Server 端、Client 端的封裝,無論是哪端,Mina 在整個網通通訊結構中都處於如下的位置:可見Mina 的API 將真正的網路通訊與我們的應用程式隔離開來,你只需要關心你要傳送、接收的資料以及你的業務邏輯即可。同樣的,無論是哪端,Mina 的執行流程如下所示:
(1) IoService:這個介面在一個執行緒上負責套接字的建立,擁有自己的Selector,監聽是否有連線被建立。
(2) IoProcessor:這個介面在另一個執行緒上,負責檢查是否有資料在通道上讀寫,也就是說它也擁有自己的Selector,這是與我們使用Java NIO 編碼時的一個不同之處,通常在JavaNIO 編碼中,我們都是使用一個Selector,也就是不區分IoService與IoProcessor 兩個功能介面。另外,IoProcessor 負責呼叫註冊在IoService 上的過濾器,並在過濾器鏈之後呼叫IoHandler。
(3) IoFilter:這個介面定義一組攔截器,這些攔截器可以包括日誌輸出、黑名單過濾、資料的編碼(write 方向)與解碼(read 方向)等功能,其中資料的encode 與decode是最為重要的、也是你在使用Mina 時最主要關注的地方。
(4) IoHandler:這個介面負責編寫業務邏輯,也就是接收、傳送資料的地方。

  1. 伺服器端

/**
 * mina伺服器端
 * @author mazaiting
 */
public class MinaServer {
    /**
     * 監聽的埠
     */
    private static final int PORT = 9123;
    
    public static void start() throws IOException{
        // 1. 建立IoAcceptor
        IoAcceptor acceptor = new NioSocketAcceptor();
        // 2. 加入日誌記錄過濾器,用SL4J庫記錄資訊
        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        // 3. 加入編碼過濾器,用於解碼所有收到的資訊,使用 new TextLineCodecFactory() r
        // 傳送的資訊進行編碼,返回是MINA自帶的,功能有限,只能處理文字戒者String型別。
        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"))));
        // 4. 設定ServerHandler, 自定義的Handler,TimeServerHandler
        acceptor.setHandler(new TimerServerHandler());
        // 5. 設定Session的對應I/O processor讀快取區大小2048,通常這個引數不需要設定
        acceptor.getSessionConfig().setReadBufferSize(2048);
        // 6. 設定空閒時間, 這裡的BOTH_IDLE指EADER_IDLE和WRITER_IDLE都為10秒
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        // 7. 繫結監聽埠9123.
//      acceptor.bind(new InetSocketAddress("localhost",PORT));
        acceptor.bind(new InetSocketAddress(PORT)); 
    }
    
    public static void main(String[] args) throws IOException {
        start();
    }
    
    /**
     * 伺服器端訊息處理器
     * @author mazaiting
     */
    public static class TimerServerHandler extends IoHandlerAdapter{
        @Override
        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
            /**
             * 自定義異常處理, 要不然異常會被“吃掉”;
             */
            cause.printStackTrace();
        }
        @Override
        public void messageReceived(IoSession session, Object message) throws Exception {
            /**
             * 對接收到的訊息(已經解碼)迕行下一步處理,這裡對收到的字串進行判斷,
             * 如果是”quit”則斷開連線;否則輸出當前時間的字串格式;
             */
            String str = message.toString();
            if (str.trim().equalsIgnoreCase("quit")) {
                session.closeNow();
                return;
            }
            Date date = new Date();
            session.write(date.toString());
            System.out.println("Message written...");
        }
        @Override
        public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
            /**
             * 當Session處於IDLE狀態的時候,輸出空閒狀態次數;
             */
            System.out.println("IDLE:" + session.getIdleCount(status));
        }
    }
    
}

執行程式碼,在cmd(命令提示符) 中輸入”telnet 127.0.0.1 9123″,連線成功後隨意輸入字元,並按下回車,即可看到當前時間。

  1. 客戶端

/**
 * mina客戶端
 * @author mazaiting
 */
public class MinaClient {

    /**
     * 監聽的埠
     */
    private static final int PORT = 9123;
    
    public static void start() {
        IoConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(30000);
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"), 
                LineDelimiter.WINDOWS.getValue(),
                LineDelimiter.WINDOWS.getValue())));
        connector.setHandler(new ClientHandler("你好!
 大家好!"));
        connector.connect(new InetSocketAddress("localhost", 9123));        
    }
    
    public static void main(String[] args) {
        start();
    }
    
    
    private static class ClientHandler extends IoHandlerAdapter{
        private String values;
        public ClientHandler(String values) {
            this.values = values;
        }
        @Override
        public void sessionOpened(IoSession session) throws Exception {
            session.write(values);
        }
        @Override
        public void messageReceived(IoSession session, Object message) throws Exception {
            System.out.println(message.toString());
        }
    }
}


相關文章