轉載:Apache Mina 入門實例


這個教程是介紹使用Mina搭建基礎示例。這個教程內容是以建立一個時間服務器。java


如下是這個教程須要準備的東西:apache

  • MINA 2.0.7 Coreapi

  • JDK 1.5 或更高服務器

  • SLF4J 1.3.0 或更高session

  • Log4J 1.2 用戶: slf4j-api.jar, slf4j-log4j12.jar, 和Log4J 1.2.x框架

  • Log4J 1.3 用戶: slf4j-api.jar, slf4j-log4j13.jar, 和Log4J 1.3.xsocket

  • java.util.logging 用戶: slf4j-api.jar 和slf4j-jdk14.jaride

  • 重要提醒:請確認你使用的slf4j-*.jar和你的logging框架匹配。舉個板栗,slf4j-log4j12.jar 和 log4j-1.3.x.jar 是不能混在一塊兒用的,不然會出問題。ui

建立一個MINA時間服務

We will begin by creating a file called MinaTimeServer.java
咱們建立一個文件名爲 MinaTimeServer.java ,文件內容以下:this

publicclassMinaTimeServer{publicstaticvoid main(String[] args ){//尚未東西呢}}

上面的代碼應該不用解釋了吧,爲了建立咱們的服務,咱們須要一個監聽傳入鏈接的對象,因爲咱們的項目是基於TCP/IP,因此須要一個SocketAcceptor 對象來幫咱們處理。

import org.apache.mina.core.service.IoAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;publicclassMinaTimeServer{publicstaticvoid main(String[] args ){IoAcceptor acceptor =newNioSocketAcceptor();}}

建立好後,咱們能夠定義處理請求的類,和指定監聽的端口等。

接下來,咱們須要在配置裏添加幾個過濾器。第一個是logger,這個過濾器用來記錄全部的信息,好比建立session(會話),接收消息,發送消息,關閉會話等。第二個是ProtocolCodecFilter(協議編解碼過濾器).這個過濾器用來轉換二進制或協議的專用數據到消息對象中, 反之亦然。咱們這裏使用一個已經存在的TextLine工廠,由於咱們這裏只處理一些文字消息(你不須要再去寫編解碼部分)。

import java.nio.charset.Charset;import org.apache.mina.core.service.IoAcceptor;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;publicclassMinaTimeServer{publicstaticvoid main(String[] args ){IoAcceptor acceptor =newNioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger",newLoggingFilter());
        acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));}}

For this tutorial, we will extend the class IoHandlerAdapter. This is a class that follows the adapter design pattern which simplifies the amount of code that needs to be written in order to satisfy the requirement of passing in a class that implements the IoHandler interface.
接下來咱們須要建立一個handler來實時處理客戶端的鏈接和請求,這個handler 類必須實現 IoHandler這個接口。對於全部使用MINA的程序來講,主要的負荷都在這個文件,它爲全部客戶端請求提供服務。在這個例子中,咱們將擴展IoHandlerAdapter類。這是一個聽從適配器模式的類,幫咱們簡化了不少爲了去實現IoHandler接口的代碼。

import java.io.IOException;import java.nio.charset.Charset;import org.apache.mina.core.service.IoAcceptor;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;publicclassMinaTimeServer{publicstaticvoid main(String[] args )throwsIOException{IoAcceptor acceptor =newNioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger",newLoggingFilter());
        acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

        acceptor.setHandler(newTimeServerHandler());}}

如今咱們要添加一些NioSocketAcceptor 配置,這將容許咱們設置特殊的socket設置來接收客戶端的鏈接。

import java.io.IOException;import java.nio.charset.Charset;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.service.IoAcceptor;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;publicclassMinaTimeServer{publicstaticvoid main(String[] args )throwsIOException{IoAcceptor acceptor =newNioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger",newLoggingFilter());
        acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

        acceptor.setHandler(newTimeServerHandler());

        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);}}

這有兩行新代碼,這些方法是用來爲會話設置IoHandler,輸入緩衝區的大小和空閒等待時間。
須要指定緩衝區大小來告訴底層操做系統爲傳入的數據分配多少的空間。第二行指定多少時間沒有讀寫操做就進入空閒狀態。

handler的代碼以下:

import java.util.Date;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;publicclassTimeServerHandlerextendsIoHandlerAdapter{@Overridepublicvoid exceptionCaught(IoSession session,Throwable cause )throwsException{
        cause.printStackTrace();}@Overridepublicvoid messageReceived(IoSession session,Object message )throwsException{String str = message.toString();if( str.trim().equalsIgnoreCase("quit")){
            session.close();return;}Date date =newDate();
        session.write( date.toString());System.out.println("Message written...");}@Overridepublicvoid sessionIdle(IoSession session,IdleStatus status )throwsException{System.out.println("IDLE "+ session.getIdleCount( status ));}}

這個類中通常有exceptionCaughtmessageReceived 和 sessionIdle這幾個方法。exceptionCaught 應該老是在handler 中定義,來處理一些異常狀況,不然異常信息將沒法捕捉。

exceptionCaught 方法簡單地打印了錯誤的堆棧跟蹤和關閉會話。對於大多數程序,這將是標準的作法,除非處理程序能夠從異常狀態中恢復。

messageReceived 方法來處理從客戶端接收到的數據,這裏是將當前時間返回給客戶端,當收到quit時,會話將被關閉,也會返回一個當前時間給客戶端。根據所使用的協議編解碼器,object 這個參數傳遞的類型有所不一樣,以及返回的數據時的session.write(Object) 也不一樣。若是不指定協議的編解碼器,你將收到一個類型爲IoBuffer 的對象,返回的數據也要求是IoBuffer

The sessionIdle method will be called once a session has remained idle for the amount of time specified in the call acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );.
sessionIdle 方法將定時調用一次會話,保持空閒狀態。經過調用acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );來設定時間間隔。

全部剩下要作的就是定義套接字地址,該服務器將偵聽,實際接入時纔會啓動服務。

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;publicclassMinaTimeServer{privatestaticfinalint PORT =9123;publicstaticvoid main(String[] args )throwsIOException{IoAcceptor acceptor =newNioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger",newLoggingFilter());
        acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

        acceptor.setHandler(newTimeServerHandler());
    acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);
        acceptor.bind(newInetSocketAddress(PORT));}}

到了這裏後,服務端的操做就已經完成了,客戶端可參考附件中代碼,裏面包含了完整的實例,來源自http://blog.csdn.net/hujunil/article/details/9923381

代碼結構

代碼結構

效果

客戶端
mina-2.jpg
服務端
mina-3.jpg

相關文章
相關標籤/搜索