首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

MINA(三)Understand MINA2 and Calculate Spring Example

2012-11-05 
MINA(3)Understand MINA2 and Calculate Spring ExampleMINA(3)Understand MINA2 and Calculate Spring Ex

MINA(3)Understand MINA2 and Calculate Spring Example
MINA(3)Understand MINA2 and Calculate Spring Example

1. Process
read in data     --------> IoAcceptor
write out data             IoConnector ----------> Thread Pool(IoProcessor) --------> IoFilter IoFilter ExecutorFilter ---> IoHandler

Read in Data
IO ---> IoProcessor ----> logging, decode, thread pool (IoFilter) -----> IoHandler(business logic)

Write out Data
IoHandler(business logic) ----> logging, encode, thread pool (IoFilter) -----> IO (IoProcessor)

2. Threads
IoAcceptor/IoConnector
IoProcessor
IoHandler

IoAcceptor/IoConnector
IoAcceptor will accept the connection from client, it will create one thread per one port. IoConnector will use for create connection to server side.

IoProcessor
IoProcessor will handle the IO things for IoAcceptor and IoConnector.
IoConnector connector = new NioSocketConnector(9);  
IoAcceptor acceptor = new NioSocketAcceptor(9);

IoHandler

Event of creating Thread and running Thread
IoAcceptor/IoConnector Pool ------> IoProcessor Pool

IoAcceptor/IoConnector create socket connection (IoAcceptor bind(), IoConnector.connect()), system will get a thread from pool, binding or connecting the socket channal.

IoAcceptor/IoConnector received the socket request, system create IoSession object, get one thread from IoProccessor, handle the IO task.

Handle the IoHandler from thread pool if the system configured one.

2. Make it works with Spring with a Simple Example

Using the Calculate Example
pom.xml as follow:
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.6.6</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>
<dependency>
  <groupId>org.apache.mina</groupId>
  <artifactId>mina-core</artifactId>
  <version>2.0.4</version>
</dependency>
<dependency>
  <groupId>org.apache.mina</groupId>
  <artifactId>mina-integration-spring</artifactId>
  <version>1.1.7</version>
</dependency>
<dependency>
  <groupId>org.apache.mina</groupId>
  <artifactId>mina-integration-beans</artifactId>
  <version>2.0.4</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.6.6</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>3.1.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>3.1.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>3.1.2.RELEASE</version>
</dependency>
...snip...
<build>
    <finalName>easynio</finalName>
    <plugins>
        <plugin> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>maven-bundle-plugin</artifactId> 
    <extensions>true</extensions> 
</plugin>
    </plugins>
  </build>

The spring Configuration file is as follow:

    <bean >
        <property name="customEditors" >
            <map>
                <entry key="java.net.SocketAddress" >
                    <bean />
                </entry>
            </map>
        </property>
    </bean>
   
    <!-- The IoHandler implementation -->
    <bean id="calculateHandler" />
   
    <!-- the IoFilters -->
    <bean id="executorFilter" />
    <bean id="mdcInjectionFilter" >
        <constructor-arg value="remoteAddress" />
    </bean>
    <bean id="codecFilter" >
        <constructor-arg>
            <bean />
        </constructor-arg>
    </bean>
    <bean id="loggingFilter" />
    <!-- The non-SSL filter chain. -->
    <bean id="filterChainBuilder" >
        <property name="filters" >
            <map>
                <entry key="executor" value-ref="executorFilter" />
                <entry key="mdcInjectionFilter" value-ref="mdcInjectionFilter" />
                <entry key="codecFilter" value-ref="codecFilter" />
                <entry key="loggingFilter" value-ref="loggingFilter" />
            </map>
        </property>
    </bean>
   
    <!-- The IoAcceptor which binds to port 1235 server side -->
    <bean id="minaAcceptor" init-method="bind" >
        <property name="defaultLocalAddress" value=":12345" />
        <property name="handler" ref="calculateHandler" />
        <property name="reuseAddress" value="true" />
        <property name="filterChainBuilder" ref="filterChainBuilder" />
    </bean>


The business logic handler class is as follow:
package com.sillycat.easynio.plugins.mina.businesshandlers;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CalculateHandler extends IoHandlerAdapter {

private final Logger logger = LoggerFactory.getLogger(getClass());

private ScriptEngine jsEngine = null;

public CalculateHandler() {
ScriptEngineManager sfm = new ScriptEngineManager();
jsEngine = sfm.getEngineByName("JavaScript");
if (jsEngine == null) {
throw new RuntimeException("No Java Script Engine.");
}
}

public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
logger.warn(cause.getMessage(), cause);
}

public void messageReceived(IoSession session, Object message)
throws Exception {
String expression = message.toString();
if ("quit".equalsIgnoreCase(expression.trim())) {
session.write("Closing the session!".toString());
session.close(true);
return;
}
try {
Object result = jsEngine.eval(expression);
if(result != null){
session.write(result.toString());
}else{
session.write("No result!");
}
} catch (ScriptException e) {
logger.warn(e.getMessage(), e);
session.write("Wrong expression, try again.");
}
}

}

error message
Missing artifact org.apache.mina:mina-core:bundle:2.0.4

solution
  <build>
    <finalName>easynio</finalName>
    <plugins>
        <plugin> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>maven-bundle-plugin</artifactId> 
    <extensions>true</extensions> 
</plugin>
    </plugins>
  </build>

We can use the telnet tool on win7 to verify the 3 + 3 = 6 or some other calculating things.

Or we can use client class as follow:
package com.sillycat.easynio.plugins.mina.businesshandlers;

import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.core.service.IoHandlerAdapter;
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;

public class CalculateClientHandler extends IoHandlerAdapter {

private static final IoFilter LOGGING_FILTER = new LoggingFilter();

private static final IoFilter CODEC_FILTER = new ProtocolCodecFilter(
new TextLineCodecFactory());

public void sessionCreated(IoSession session) throws Exception {
session.getFilterChain().addLast("codec", CODEC_FILTER);
session.getFilterChain().addLast("logger", LOGGING_FILTER);
}

public void messageReceived(IoSession session, Object message)
throws Exception {
String msg = (String) message;
System.out.println("Client Received: " + msg);
}

}

package com.sillycat.easynio.plugins.mina.client;

import java.net.InetSocketAddress;
import java.net.SocketAddress;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.sillycat.easynio.plugins.mina.businesshandlers.CalculateClientHandler;

public class MinaClientSupport {

private IoHandler handler = null;

private String host;

private IoSession session = null;

private int port;

public boolean send(Object message) {
SocketAddress address = new InetSocketAddress(host, port);
NioSocketConnector connector = new NioSocketConnector();
try {
if (session == null) {
connector.getFilterChain().addLast("mdc",
new MdcInjectionFilter());
connector.setHandler(handler);
ConnectFuture future1 = connector.connect(address);
future1.awaitUninterruptibly();
if (!future1.isConnected()) {
return false;
}
session = future1.getSession();
}
session.write(message);
return true;
} catch (Exception e) {
return false;
}
}

public void close() {
if (session != null) {
if (session.isConnected()) {
// Wait until the chat ends.
session.getCloseFuture().awaitUninterruptibly();
}
session.close(true);
}
}

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public int getPort() {
return port;
}

public void setPort(int port) {
this.port = port;
}

public void setHandler(IoHandler handler) {
this.handler = handler;
}

public static void main(String[] args) throws InterruptedException {
System.out.println("Application Test:");
MinaClientSupport client = new MinaClientSupport();
CalculateClientHandler handler = new CalculateClientHandler();
client.setHandler(handler);
client.setHost("localhost");
client.setPort(12345);
String msg = "1+3*6";
client.send(msg);
System.out.println("Client Send: " + msg);
client.send("quit");
client.close();
}

}


references:
http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html
http://www.iteye.com/topic/1112123
http://sillycat.iteye.com/blog/563765
http://www.ibm.com/developerworks/cn/java/j-lo-mina2/index.html

http://svn.apache.org/viewvc/mina/branches/1.0/example/src/main/java/org/apache/mina/example/chat/
http://mina.apache.org/user-guide.html

http://blog.csdn.net/jialechan/article/details/6821389

热点排行