1. 程式人生 > >Apache MINA實戰之 牛刀小試

Apache MINA實戰之 牛刀小試

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

本文連結:http://blog.csdn.net/kongxx/article/details/7520259

Apache的MINA是一個被用來構建高效能和高可伸縮性應用程式的網路應用框架,它提供了一套統一的建立在Java NIO之上的事件驅動的非同步API。

對於MINA框架的瞭解,MINA官方的幾篇文章是必須要看的,如下:

* Application Architecture http://mina.apache.org/mina-based-application-architecture.html
* Server Architecture http://mina.apache.org/server-architecture.html
* Client Architecture http://mina.apache.org/client-architecture.html

其中幾個主要的元件如下:

I/O Service - 用來處理I/O流,對於Server端就是IOAcceptor的實現類接受Client端的連線請求,對於Client端就是IoConnector的實現類來建立到Server端的連線。

I/O Filter Chain - 用來過濾或轉化資料。對於Server端和Client端來說都是IoFilter介面的實現類,MINA自己內建了很多IoFilter介面的實現類。具體可以參考官方文件。

I/O Handler - 用來處理真正業務邏輯的類。對於Server端和Client端來說都是IoHandler介面的實現類,通常來說需要自己編寫。


由於Server端和Client端都是基於以上三個元件的,因此對於Server端和Client端程式設計來說就都有類似的程式碼結構。

對於Server端來說:

1. 建立I/O service - 這裡就是建立IOAcceptor類監聽埠。

2. 建立I/O Filter Chain - 這裡就是告訴使用那些IoFilter。
3. 建立I/O Handler - 自己的業務邏輯。 

對於Client端來說:

1. 建立I/O service - 這裡就是建立IOConnector類來建立到Server端的連線。

2. 建立I/O Filter Chain - 這裡就是告訴使用那些IoFilter。

3. 建立I/O Handler - 自己的業務邏輯。

下面來通過一個例子看看MINA是怎樣工作的。由於大多數應用都是基於TCP/IP的應用,所以這裡也就不再說UDP/IP了。

這裡我使用了Maven來建立了一個簡單java應用程式,具體步驟請參Maven的官方手冊。這裡只是將我用到的maven配置檔案pom.xml列出,方便下面及後續文章使用。具體pom.xml檔案內容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.google.code.garbagecan.minastudy</groupId> <artifactId>minastudy</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>minastudy</name> <url>http://maven.apache.org</url> <dependencies>  <dependency>   <groupId>org.apache.mina</groupId>   <artifactId>mina-core</artifactId>   <version>2.0.4</version>  </dependency>  <dependency>   <groupId>org.apache.mina</groupId>   <artifactId>mina-filter-compression</artifactId>   <version>2.0.4</version>  </dependency>  <dependency>   <groupId>org.slf4j</groupId>   <artifactId>slf4j-api</artifactId>   <version>1.3.0</version>  </dependency>  <dependency>   <groupId>org.slf4j</groupId>   <artifactId>slf4j-log4j12</artifactId>   <version>1.3.0</version>  </dependency> </dependencies></project>
首先來看Server端的程式碼

package com.google.code.garbagecan.minastudy.sample1;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.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;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;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class MyServer {  private static final Logger logger = LoggerFactory.getLogger(MyServer.class);  public static void main(String[] args) {  IoAcceptor acceptor = new NioSocketAcceptor();  acceptor.getFilterChain().addLast("logger", new LoggingFilter());  acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));  acceptor.setHandler(new IoHandlerAdapter() {      @Override   public void sessionCreated(IoSession session) throws Exception {   }      @Override   public void sessionOpened(IoSession session) throws Exception {   }   @Override   public void sessionClosed(IoSession session) throws Exception {   }   @Override   public void sessionIdle(IoSession session, IdleStatus status) throws Exception {   }   @Override   public void exceptionCaught(IoSession session, Throwable cause) throws Exception {    logger.error(cause.getMessage(), cause);    session.close(true);   }   @Override   public void messageReceived(IoSession session, Object message) throws Exception {    logger.info("Received message " + message);    session.write(message);   }   @Override   public void messageSent(IoSession session, Object message) throws Exception {    logger.info("Sent message " + message);   }  });    try {   acceptor.bind(new InetSocketAddress(10000));  } catch (IOException ex) {   logger.error(ex.getMessage(), ex);  } }}
1. 首先建立I/O Service,這裡使用的是NioSocketAcceptor類來建立了一個IoAcceptor例項。

2. 建立I/O Filter Chain,這裡使用了兩個IoFilter,一個是LoggingFilter用來記錄日誌和列印事件訊息,另一個是ProtocolCodecFilter例項用來編碼資料,這裡其實就是將傳遞的資料編碼成文字。

3. 建立I/O Handler,不要害怕,看起來程式碼多,其實就是一個實現了IoHandler介面的子類,自己需要實現其中的一些方法,這裡方法比較多,但是我在這裡只實現了messageSent,messageReceived和exceptionCaught方法。

4. 最後就是讓IoAcceptor類例項繫結埠實現監聽。

下面看看Client端的程式碼

package com.google.code.garbagecan.minastudy.sample1;import java.net.InetSocketAddress;import java.nio.charset.Charset;import org.apache.mina.core.RuntimeIoException;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.service.IoConnector;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;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;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class MyClient {  private static final Logger logger = LoggerFactory.getLogger(MyClient.class);  public static void main(String[] args) {  IoConnector connector = new NioSocketConnector();  connector.setConnectTimeoutMillis(10 * 1000);    connector.getFilterChain().addLast("logger", new LoggingFilter());  connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));    connector.setHandler(new IoHandlerAdapter() {      @Override   public void sessionCreated(IoSession session) throws Exception {   }   @Override   public void sessionOpened(IoSession session) throws Exception {    for (int i = 0; i < 10; i++) {     session.write("Hello user_" + i);    }    session.write("Bye");   }   @Override   public void sessionClosed(IoSession session) throws Exception {   }   @Override   public void sessionIdle(IoSession session, IdleStatus status) throws Exception {   }   @Override   public void exceptionCaught(IoSession session, Throwable cause) throws Exception {    logger.error(cause.getMessage(), cause);    session.close(true);   }   @Override   public void messageReceived(IoSession session, Object message) throws Exception {    logger.info("Received message " + message);    if (message.toString().equalsIgnoreCase("Bye")) {     session.close(true);    }   }   @Override   public void messageSent(IoSession session, Object message) throws Exception {    logger.info("Sent message " + message);   }  });  IoSession session = null;  try {   ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 10000));   future.awaitUninterruptibly();   session = future.getSession();  } catch (RuntimeIoException e) {   logger.error(e.getMessage(), e);  }  session.getCloseFuture().awaitUninterruptibly();  connector.dispose(); }}

1. 首先建立I/O Service,這裡使用的是NioSocketConnector類來建立了一個IoConnector例項,並設定連線超時為10秒。

2. 建立I/O Filter Chain,和伺服器端同樣設定了兩個IoFilter,一個是LoggingFilter用來記錄日誌和列印事件訊息,另一個是ProtocolCodecFilter例項用來編碼資料,這裡其實就是將傳遞的資料編碼成文字。

3. 建立I/O Handler,也不要害怕,看起來程式碼多,其實也是一個實現了IoHandler介面的子類,並且自己實現了sessionOpened,messageSent,messageReceived和exceptionCaught方法。實現sessionOpened方法是為了在建立連線後向Server端傳送訊息。另外看一下messageReceived方法實現,在接收到伺服器端的訊息後關閉會話。從而可以使Client程式最終能夠退出。

4. 最後就是IoConnector例項類連線遠端的Server。

 

下面測試一下上面的程式,首先執行MyServer類,然後執行MyClient類,就可以分別在各自的終端上看到事件日誌以及傳送/接收的訊息了。

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述