日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

MINA 基礎學習一

系統 2034 0

?

一、IoService接口

1、作用:IoService是創建服務的頂層接口,無論客戶端還是服務端,都是從它繼承實現的。

2、類結構

常用接口為:IoService,IoAcceptor,IoConnector

常用類為:NioSocketAcceptor,NioSocketConnector

類圖如下:

MINA 基礎學習一

?

?

先提出兩個問題:

1. 為什么有了IoService接口還要定義AbstractIoService抽象類?

2. AbstractIoService抽象類與IoAcceptor(IoConnector)有什么區別?

分析:

? ? 1. IoService接口聲明了服務端的共有屬性和行為;

? ? 2. IoAcceptor接口繼承了IoService接口,并添加了服務端特有的接口屬性及方法,比如bind()方法,成為典型的服務端接口;

? ? 3. IoConnector接口同樣繼承了IoService接口,并添加了客戶端特有的接口屬性及方法,比如connect()方法,成為典型的客戶端接口;

---- IoService是IoAcceptor和IoConnector父接口,為什么不直接定義IoAcceptor和IoConnector接口呢,因為它們有共同的特點,比如共同屬性,管理服務的方法等,所有IoService的出現是為了代碼復用。

? ? 4. AbstractIoService實現了IoService中管理服務的方法,比如getFilterChainBuilder方法---獲得過濾器鏈;

----為什么有了IoService接口還要定義AbstractIoService抽象類?一樣為了代碼的復用!AbstractIoService抽象類實現了服務端或客戶端的共有的管理服務的方法,不需要讓IoService接口的子類重復的實現這些方法;

? ? 5. AbstractIoAcceptor抽象類繼承了AbstractIoService抽象類并實現了IoAcceptor接口,成為了擁有管理服務端實現功能的服務端類;我們常用的NioSocketAcceptor就是它的子類;

? ? 6. AbstractIoConnector抽象類繼承了AbstractIoService抽象類并實現了IoConnector接口,成為了擁有管理客戶端實現功能的客戶端類;我們常用的NioSocketConnector就是它的子類;

----AbstractIoService抽象類與IoAcceptor(IoConnector)有什么區別?很清楚,AbstractIoService抽象類實現的是共有的管理服務的方法,只有管理功能的一個類;而兩個接口卻是不同的兩個服務角色----一個客戶端,一個服務端。

        //創建一個非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
//創建一個非阻塞的客戶端
IoConnector connector = new NioSocketConnector();
      
二、IoSessionConfig

獲得IoSession的配置對象IoSessionConfig,通過它可以設置Socket連接的一些選項。

a. void setReadBufferSize(int size)

這個方法設置讀取緩沖的字節數,但一般不需要調用這個方法,因為IoProcessor?會自動調整緩沖的大小。你可以調用setMinReadBufferSize()、setMaxReadBufferSize()方法,這樣無論IoProcessor?無論如何自動調整,都會在你指定的區間。

b. void setIdleTime(IdleStatus status,int idleTime):

?

這個方法設置關聯在通道上的讀、寫或者是讀寫事件在指定時間內未發生,該通道就進入空閑狀態。一旦調用這個方法,則每隔idleTime都會回調過濾器、IoHandler中的sessionIdle()方法。

?

c. void setWriteTimeout(int time):

這個方法設置寫操作的超時時間。

d. void setUseReadOperation(boolean useReadOperation):

這個方法設置IoSession?的read()方法是否可用,默認是false。

?

?

          // 獲得IoSessionConfig對象
IoSessionConfig cfg=acceptor.getSessionConfig();
// 設置讀取數據的緩沖區大小()
cfg.setReadBufferSize(2048);
// 讀寫通道10秒內無操作進入空閑狀態
cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10);
// 寫操作超時時間10秒
cfg.setWriteTimeout(10);
        
?
三、 IoFilter接口

Mina 最主要的工作就是把底層傳輸的字節碼轉換為 Java 對象,提供給應用程序;或者把應用程序返回的結果轉換為字節碼,交給底層傳輸 。這些都是由 IoFilter 完成的,因此 IoFilter Mina 的精髓所在。

Mina 程序中, IoFilter 是必不可少的;有了它, Mina 的層次結構才異常清晰:

IoFilter?? ----?? 消息過濾

IoHandler? ----?? 業務處理

??? Filter ,過濾器的意思。 IoFilter I/O 操作的過濾器。 IoFilter Servlet 中的過濾器一樣,主要用于攔截和過濾網絡傳輸中 I/O 操作的各種消息。在 Mina 的官方文檔中已經提到了 IoFilter 的作用:

1 )記錄事件的日志( Mina 默認提供了 LoggingFilter

2 )測量系統性能

3 )信息驗證

4 )過載控制

5 )信息的轉換 ( 主要就是編碼和解碼 )

6 )和其他更多的信息

??? IoService 實例會綁定一個 DefaultIoFilterChainBuilder ---- 過濾器鏈,我們把自定義的各種過濾器( IoFilter )自由的插放在這個過濾器鏈上了,類似于一種可插拔的功能!

2.2.1 類結構

常用接口為: IoFilter IoFilterChainBuilder

常用類為: IoFilterAdapter DefaultIoFilterChainBuilder

ProtocolCodecFilter LoggingFilter

類圖如下:

先提出兩個問題:

1. 在IoService中如何添加多個IoFilter?

2. 如何自定義協議編解碼器?

分析:

a. IoFilter有2個實現類:IoFilterAdapter是個抽象的適配器類,我們可以根據需要擴展這個類,并且有選擇的覆蓋過濾器的方法;所有方法的默認把事件轉發到下一個過濾器;查看源碼如下:

?

?

        public void sessionOpened(NextFilter nextFilter, IoSession session)throws Exception {
        nextFilter.sessionOpened(session);
  }
      
?

?

b .ReferenceCountingFilter封裝了IoFilter實例,監看調用該filter的對象的個數,如果沒有任何對象調用該IoFilter,就自動銷毀IoFilter;查看源碼如下:

?

?

        public class ReferenceCountingFilter implements IoFilter {
    private final IoFilter filter;
 
    private int count = 0;
 
    public ReferenceCountingFilter(IoFilter filter) {
        this.filter = filter;
    }
 
    public void init() throws Exception {
        // no-op, will init on-demand in pre-add if count == 0
    }
    public void destroy() throws Exception {
           } ……………略
      
?

?

c. 實現 IoFilterAdapter 的類有多個,但是我們使用最多的就是

ProtocolCodecFilter---- 它是我們自定義編解碼器的入口

?

添加過濾器----在IoService中如何添加多個IoFilter?如何代碼,我添加了2個過濾器:LoggingFilter和TextLineCodecFactory(源碼為入門的服務端程序)

        // 創建一個非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 設置日志過濾器
acceptor.getFilterChain().addLast("logger",new LoggingFilter());
// 設置過濾器(使用Mina提供的文本換行符編解碼器)
acceptor.getFilterChain().addLast(
		"codec",
		new ProtocolCodecFilter(new TextLineCodecFactory(Charset
				.forName("UTF-8"),
				LineDelimiter.WINDOWS.getValue(),
				LineDelimiter.WINDOWS.getValue())));
// 獲得IoSessionConfig對象
IoSessionConfig cfg = acceptor.getSessionConfig();
// 讀寫通道10秒內無操作進入空閑狀態
cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10);

// 綁定邏輯處理器
acceptor.setHandler(new Demo1ServerHandler());
// 綁定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服務端啟動成功...     端口號為:" + PORT);
      

?

如果要是使用LoggingFilter類,則需要需要導入slf4j-log4j12-1.7.5.jar、slf4j-api-1.7.5.jar、log4j-1.2.13.jar三個包,然后在src目錄下面添加log4j的配置文件

?

?

        log4j.rootLogger=DEBUG,MINA,file

log4j.appender.MINA=org.apache.log4j.ConsoleAppender    
 
log4j.appender.MINA.layout=org.apache.log4j.PatternLayout    
log4j.appender.MINA.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss,SSS} %-5p %c{1} %x - %m%n

log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/minademos.log
log4j.appender.file.MaxFileSize=5120KB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[VAMS][%d] %p | %m | [%t] %C.%M(%L)%n

      

?

?四、IoHandler接口

?

IoHandler是Mina實現其業務邏輯的頂級接口;它相當簡單,你就理解它是根據事件觸發的簡單應用程序即可。

在IoHandler中定義了7個方法,根據I/O事件來觸發對應的方法:

?

        import java.io.IOException;
public interface IoHandler {
    void sessionCreated(IoSession session) throws Exception;
    void sessionOpened(IoSession session) throws Exception;
    void sessionClosed(IoSession session) throws Exception;
    void sessionIdle(IoSession session, IdleStatus status) throws Exception;
    void exceptionCaught(IoSession session, Throwable cause) throws Exception;
    void messageReceived(IoSession session, Object message) throws Exception;
    void messageSent(IoSession session, Object message) throws Exception;
}

      

?

sessionCreated:當一個新的連接建立時,由I/O processor thread調用;

?

sessionOpened:當連接打開是調用;

?

messageReceived:當接收了一個消息時調用;

?

messageSent:當一個消息被(IoSession#write)發送出去后調用;

?

sessionIdle:當連接進入空閑狀態時調用;

?

sessionClosed:當連接關閉時調用;

?

exceptionCaught:當實現IoHandler的類拋出異常時調用;

?

? ? 一般情況下,我們最關心的只有messageReceived方法,接收消息并處理,然后調用IoSession的write方法發送出消息!(注意:這里接收到的消息都是Java對象,在IoFilter中所有二進制數據都被解碼啦!)

?

? ? 一般情況下很少有人實現IoHandler接口,而是繼承它的一個實現類IoHandlerAdapter,這樣不用覆蓋它的7個方法,只需要根據具體需求覆蓋其中的幾個方法就可以!

?

Iohandler的7個方法其實是根據session的4個狀態值間變化來調用的:

?

Connected:會話被創建并使用;

?

Idle:會話在一段時間(可配置)內沒有任何請求到達,進入空閑狀態;

?

Closing:會話將被關閉(剩余message將被強制flush);

?

Closed:會話被關閉;

?

?

狀態轉換圖如下

? MINA 基礎學習一

?

MINA 基礎學習一


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 五寨县| 德兴市| 来宾市| 宿迁市| 桂平市| 巴青县| 福贡县| 扎赉特旗| 武安市| 宽甸| 轮台县| 罗甸县| 嘉祥县| 和政县| 东兰县| 施秉县| 吉林市| 高要市| 牙克石市| 丹阳市| 永顺县| 中山市| 斗六市| 阿瓦提县| 龙口市| 麻江县| 东兰县| 湄潭县| 泽普县| 江西省| 乳山市| 安化县| 遂川县| 新民市| 房产| 榕江县| 漠河县| 得荣县| 漳平市| 准格尔旗| 禄丰县|