当前位置:文档之家› MiNa

MiNa

MiNa
MiNa

Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily. It provides an abstract · event-driven · asynchronous API over various transports such as TCP/IP and UDP/IP via Java NIO.

Apache MINA is often called:

NIO framework · library,

client · server framework · library, or

a networking · socket library.

On Saturday, 25 September 2010, the Apache MINA project is pleased to announce MINA 2.0.0 ! This version fixes many issues found since we released 2.0.0-RC1.

We recommend all users to upgrade to this release. We consider this a stable and production ready release.

这是官方网上的说明。

其实之前已经学过Mina了,但现在也忘得差不多了,趁Apache发布新版本的时候,学一学新版本上的东西,顺便复习一下以前学过的知识。

本文是入门篇,先来写一个简单的socket server服务器程序,可以用telnet 来连接,当服务器收到客户端的连接时会把服务器上的时间返回给客户。

首先引入四个包:

mina-core-2.0.0.jar

slf4j-api-1.6.1.jar

slf4j-jdk14-1.6.1.jar

slf4j-log4j12-1.6.1.jar

接着创建一个主服务类:MinaTimeServer

import java.io.IOException;

import https://www.doczj.com/doc/8f13432251.html,.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;

public class MinaTimeServer {

public static void main(String[] args) throws IOException {

IoAcceptor acceptor = new NioSocketAcceptor();

//This filter will log all information such as newly created

//sessions, messages received, messages sent, session closed acceptor.getFilterChain().addLast("logger", new LoggingFilter());

//This filter will translate binary or protocol specific data into

//message object and vice versa. We use an existing TextLine

//factory because it will handle text base message for you (

//you don't have to write the codec part)

acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(

new TextLineCodecFactory(Charset.forName("UTF-8"))));

acceptor.setHandler(new TimeServerHandler());

acceptor.getSessionConfig().setReadBufferSize(BUF_SIZE);

//the first parameter defines what actions to check for when

//determining if a session is idle, the second parameter defines

//the length of time in seconds that must occur before a session

//is deemed to be idle.

acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);

acceptor.bind(new InetSocketAddress(PORT));

}

private static final int PORT = 8181,BUF_SIZE = 2048;

}

再创建一个handler来管理事件

view plaincopy to clipboardprint?

package mina;

import java.util.Date;

import org.apache.mina.core.service.IoHandlerAdapter;

import org.apache.mina.core.session.IdleStatus;

import org.apache.mina.core.session.IoSession;

public class TimeServerHandler extends IoHandlerAdapter {

@Override

public void exceptionCaught(IoSession session, Throwable cause)

throws Exception {

cause.printStackTrace();

}

@SuppressWarnings("deprecation")

@Override

public void messageReceived(IoSession session, Object message)

throws Exception {

String str = message.toString();

System.out.println("Message received:"+str);

if(str.trim().equalsIgnoreCase("quit")){

session.close();

return;

}

Date date = new Date();

session.write(date.toString());

System.out.println("Message written.");

}

@Override

public void messageSent(IoSession session, Object message) throws Exception { super.messageSent(session, message);

}

@Override

public void sessionClosed(IoSession session) throws Exception {

super.sessionClosed(session);

}

@Override

public void sessionCreated(IoSession session) throws Exception {

super.sessionCreated(session);

}

@Override

public void sessionIdle(IoSession session, IdleStatus status)

throws Exception {

System.out.println("IDLE"+session.getIdleCount(status));

}

@Override

public void sessionOpened(IoSession session) throws Exception {

// TODO Auto-generated method stub

super.sessionOpened(session);

}

}

上一篇只写了一个服务端。这一次来构建一个客户端。

首先,在引入上一篇中讲到的几个jar包处,还要引入一个mina-example-2.0.0.jar

本程序的主要功能是,客户端向服务器发送几个数字,然后服务器给客户端返回结果。文

字就不多写了,我在上面都写了注释!

下面的服务端代码:

import java.io.IOException;

import https://www.doczj.com/doc/8f13432251.html,.InetSocketAddress;

import org.apache.mina.example.sumup.codec.SumUpProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolCodecFilter;

import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.logging.LoggingFilter;

import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class MinaServer {

private static final int PORT = 8389,BUF_SIZE = 2048;

// Set this to false to use object serialization instead of custom codec.

private static final boolean USE_CUSTOM_CODEC = true;

public static void main(String[] args) throws IOException {

NioSocketAcceptor acceptor = new NioSocketAcceptor();

// Add 'codec' filter

if(USE_CUSTOM_CODEC){

acceptor.getFilterChain().addLast("codec",

new ProtocolCodecFilter(

new SumUpProtocolCodecFactory(false)));

} else {

acceptor.getFilterChain().addLast("codec",

new ProtocolCodecFilter(

new ObjectSerializationCodecFactory()));

}

//This filter will log all information such as newly created

//sessions, messages received, messages sent, session closed acceptor.getFilterChain().addLast("logger", new LoggingFilter());

acceptor.setHandler(new MinaServerHandler());

acceptor.getSessionConfig().setReadBufferSize(BUF_SIZE);

//the first parameter defines what actions to check for when

//determining if a session is idle, the second parameter defines

//the length of time in seconds that must occur before a session

//is deemed to be idle.

//acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 60);

acceptor.bind(new InetSocketAddress(PORT));

System.out.println("Listening on port:"+PORT);

}

}

它使用到了一个自定义的Handler来管理连接过程中的各个事件,代码如下:

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.example.sumup.ServerSessionHandler;

import org.apache.mina.example.sumup.message.AddMessage;

import org.apache.mina.example.sumup.message.ResultMessage;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class MinaServerHandler extends IoHandlerAdapter {

private static final String SUM_KEY = "sum";

private final static Logger LOGGER = LoggerFactory.getLogger(ServerSessionHandler.class);

@Override

public void exceptionCaught(IoSession session, Throwable cause)

throws Exception {

session.close(true);

cause.printStackTrace();

}

@Override

public void messageReceived(IoSession session, Object message)

throws Exception {

// client only sends AddMessage. otherwise, we will have to identify

// its type using instanceof operator.

AddMessage am = (AddMessage) message;

//Add the value to the current sum.

int sum = ((Integer) session.getAttribute(SUM_KEY)).intValue();

int value = am.getValue();

long expectedSum = (long) sum+value;

if(expectedSum > Integer.MAX_VALUE || expectedSum < Integer.MIN_VALUE){ //If the sum overflows or underflows , return error message.

ResultMessage rMessage = new ResultMessage();

rMessage.setSequence(am.getSequence()); // copy sequence

rMessage.setOk(false);

session.write(rMessage);

} else {

//sum up

sum = (int) expectedSum;

session.setAttribute(SUM_KEY,new Integer(sum));

//return the result message.

ResultMessage rmMessage = new ResultMessage();

rmMessage.setSequence(am.getSequence()); //copy sequece

rmMessage.setOk(true);

rmMessage.setValue(sum);

session.write(rmMessage);

}

}

@Override

public void messageSent(IoSession session, Object message) throws Exception { System.out.println("Message sent:"+message);

}

@Override

public void sessionIdle(IoSession session, IdleStatus status)

throws Exception {

https://www.doczj.com/doc/8f13432251.html,("Disconnecting the idle...");

//disconnect an idle client

session.close(true);

}

@Override

public void sessionOpened(IoSession session) throws Exception {

//Set idle time to 60 seconds

session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 60);

//Initial sum is 0

session.setAttribute(SUM_KEY,new Integer(0));

}

}

接下去就是客户端了。一样的,先写一个主类,然后再写一上Handler来管理事件。import https://www.doczj.com/doc/8f13432251.html,.InetSocketAddress;

import org.apache.mina.core.RuntimeIoException;

import org.apache.mina.core.future.ConnectFuture;

import org.apache.mina.core.session.IoSession;

import org.apache.mina.example.sumup.codec.SumUpProtocolCodecFactory;

import org.apache.mina.filter.codec.ProtocolCodecFilter;

import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.logging.LoggingFilter;

import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class MinaClient {

private final static long DEF_TIMEOUT = 60*1000L; //1 minute

// Set this to false to use object serialization instead of custom codec.

private static final boolean USE_CUSTOM_CODEC = true;

// Server and port

private static final int PORT = 8389;

private static final String SERVER = "127.0.0.1";

private static IoSession session;

/**

* @param args

* @throws InterruptedException

*/

public static void main(String[] args) throws InterruptedException { if (args.length == 0) {

System.out.println("Please specify the list of any integers");

return;

}

//prepare values to sum up

int len = args.length;

int[] values = new int[len];

for(int i = 0; i < len; i ++){

values[i] = Integer.parseInt(args[i]);

}

// Create TCP/IP connector.

NioSocketConnector connector = new NioSocketConnector();

//Set connect timeout

connector.setConnectTimeoutMillis(DEF_TIMEOUT);

// Add 'codec' filter

if(USE_CUSTOM_CODEC){

connector.getFilterChain().addLast("codec",

new ProtocolCodecFilter(

new SumUpProtocolCodecFactory(false)));

} else {

connector.getFilterChain().addLast("codec",

new ProtocolCodecFilter(

new ObjectSerializationCodecFactory()));

}

connector.getFilterChain().addLast("logger", new LoggingFilter());

//Start communication

connector.setHandler(new NetCatProtocolHandler(values));

//If it fails to connect to the server,

//retry it after 10 seconds!

while(true){

try{

ConnectFuture future = connector.connect(new InetSocketAddress(SERVER,PORT));

future.awaitUninterruptibly();

session = future.getSession();

break;

} catch (RuntimeIoException e) {

System.err.println("Fail to connect!");

e.printStackTrace();

Thread.sleep(10*1000L);

}

}

//Wait for the connection attempt to be finished.

session.getCloseFuture().awaitUninterruptibly();

connector.dispose();

}

}

Handler类

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.example.sumup.ClientSessionHandler;

import org.apache.mina.example.sumup.message.AddMessage;

import org.apache.mina.example.sumup.message.ResultMessage;

import org.slf4j.LoggerFactory;

public class NetCatProtocolHandler extends IoHandlerAdapter {

private int[] values;

private boolean finished;

private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ClientSessionHandler.class);

// provide a method for other class to judge whether it's finished.

public boolean isFinished() {

return finished;

}

public NetCatProtocolHandler(int[] values) {

this.values = values;

}

@Override

public void exceptionCaught(IoSession session, Throwable cause)

throws Exception {

session.close(true);

}

@Override

public void messageReceived(IoSession session, Object message)

throws Exception {

// IoBuffer buffer = (IoBuffer) message;

// while(buffer.hasRemaining()){

// System.out.println(buffer.getChar());

// }

// System.out.flush();

// server only sends ResultMessage. otherwise, we will have to identify

// its type using instanceof operator.

ResultMessage rm = (ResultMessage)message;

if(rm.isOk()){ // server returned OK code.

// if received the result message which has the last sequence

// number, it is time to disconnect.

if(rm.getSequence() == values.length - 1){

//Print the sum and disconnect.

LOGGER.warn("Server error, disconnecting...");

session.close(true);

finished = true;

}

}

}

@Override

public void messageSent(IoSession session, Object message) throws Exception { session.write(message);

System.out.println("Message sent:"+message);

}

@Override

public void sessionClosed(IoSession session) throws Exception {

System.err.println("Total "+ session.getReadBytes()+" byte(s)");

}

@Override

public void sessionIdle(IoSession session, IdleStatus status)

throws Exception {

if(status == IdleStatus.READER_IDLE) {

session.close(true);

}

}

@Override

public void sessionOpened(IoSession session) throws Exception {

// Set reader idle time to 60 seconds.

// sessionIdle(...) method will be invoked when no data is read

// for 60 seconds.

//session.getConfig().setIdleTime(IdleStatus.READER_IDLE, 60);

// send summation requests

for(int i = 0; i < values.length; i ++){

AddMessage message = new AddMessage();

message.setSequence(i);

message.setValue(values[i]);

session.write(message);

}

}

}

前面已经讲了两个实例,本篇中,我们来深入地了解一下Mina.

Apache MINA(Multipurpose Infrastructure for Network Applications) 是Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中。

(下面是从网上找来的)

Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。Apache MINA 2 可以作为开发网络应用程序的一个良好基础。

Apache MINA 是 Apache 基金会的一个开源项目,目前最新的版本是 2.0.0正式版,2010年9月底发布的。这也是我现在使用的版本。从参考资料中可以找到相关的下载信息。下面首先介绍基于 Apache MINA 的网络应用的一般架构。

基于 Apache MINA 开发的网络应用,有着相似的架构。下图给出了架构的示意图。如图 1 所示,基于 Apache MINA 的网络应用有三个层次,分别是 I/O 服务、I/O 过滤器和 I/O 处理器:

I/O 服务:I/O 服务用来执行实际的 I/O 操作。Apache MINA 已经提供了一系列支持不同协议的 I/O 服务,如 TCP/IP、UDP/IP、串口和虚拟机内部的管道等。开发人员也可以实现自己的 I/O 服务。

I/O 过滤器:I/O 服务能够传输的是字节流,而上层应用需要的是特定的对象与数据结构。I/O 过滤器用来完成这两者之间的转换。I/O 过滤器的另外一个重要作用是对输入输出的数据进行处理,满足横切的需求。多个 I/O 过滤器串联起来,形成 I/O 过滤器链。

I/O 处理器:I/O 处理器用来执行具体的业务逻辑。对接收到的消息执行特定的处理。

创建一个完整的基于 Apache MINA 的网络应用,需要分别构建这三个层次。Apache MINA 已经为 I/O 服务和 I/O 过滤器提供了不少的实现,因此这两个层次在大多数情况下可以使用已有的实现。I/O 处理器由于是与具体的业务相关的,一般来说都是需要自己来实现的。

Apache MINA 提供的是事件驱动的 API。它把与网络相关的各种活动抽象成事件。网络应用只需要对其感兴趣的事件进行处理即可。事件驱动的 API 使得基于Apache MINA 开发网络应用变得比较简单。应用不需要考虑与底层传输相关的具体细节,而只需要处理抽象的 I/O 事件。比如在实现一个服务端应用的时候,如果有新的连接进来,I/O 服务会产生 sessionOpened这样一个事件。如果该

应用需要在有连接打开的时候,执行某些特定的操作,只需要在 I/O 处理器中此事件处理方法 sessionOpened中添加相应的代码即可。

在介绍 Apache MINA 中的基本概念的细节之前,首先通过一个简单的应用来熟悉上面提到的三个层次的具体职责。

在使用 Apache MINA 开发复杂的应用之前,首先将介绍一个简单的应用。通过此应用可以熟悉上面提到的三个层次,即 I/O 服务、I/O 过滤器和 I/O 处理器。该应用是一个简单的计算器服务,客户端发送要计算的表达式给服务器,服务器返回计算结果。比如客户端发送 2+2,服务器返回 4.0作为结果。

在实现此计算器的时候,首先需要考虑的是 I/O 服务。该计算器使用 TCP/IP 协议,需要在指定端口监听,接受客户端的连接。Apache MINA 提供了基于 Java NIO 的套接字实现,可以直接使用。其次要考虑的是 I/O 过滤器。I/O 过滤器过滤所有的 I/O 事件和请求,可以用来处理横切的需求,如记录日志、压缩等。最后就是 I/O 处理器。I/O 处理器用来处理业务逻辑。具体到该应用来说,就是在接收到消息之后,把该消息作为一个表达式来执行,并把结果发送回去。I/O 处理器需要实现 org.apache.mina.core.service.IoHandler接口或者继承自

org.apache.mina.core.service.IoHandlerAdapter。该应用的 I/O 处理器的实现如清单 1 所示。

public class CalculatorHandler extends IoHandlerAdapter {

private static final Logger LOGGER = LoggerFactory .getLogger(CalculatorHandler.class);

private ScriptEngine jsEngine = null;

public CalculatorHandler() {

ScriptEngineManager sfm = new ScriptEngineManager();

jsEngine = sfm.getEngineByName("JavaScript");

if (jsEngine == null) {

throw new RuntimeException("找不到JavaScript 引擎。");

}

}

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.close(true);

return;

}

try {

Object result = jsEngine.eval(expression);

session.write(result.toString());

} catch (ScriptException e) {

LOGGER.warn(e.getMessage(), e);

session.write("Wrong expression, try again.");

}

}

}

在清单 1 中,messageReceived 由 IoHandler 接口声明。当接收到新的消息的时候,该方法就会被调用。此处的逻辑是如果传入了“quit”,则通过session.close关闭当前连接;如果不是的话,就执行该表达式并把结果通过session.write发送回去。此处执行表达式用的是 JDK 6 中提供的 JavaScript 脚本引擎。此处使用到了 I/O 会话相关的方法,会在下面进行说明。

接下来只需要把 I/O 处理器和 I/O 过滤器配置到 I/O 服务上就可以了。具体的实现如清单 2 所示。

public class CalculatorServer {

private static final int PORT = 10010;

private static final Logger LOGGER = LoggerFactory

.getLogger(CalculatorServer.class);

public static void main(String[] args) throws IOException {

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 CalculatorHandler());

acceptor.bind(new InetSocketAddress(PORT));

https://www.doczj.com/doc/8f13432251.html,("计算器服务已启动,端口是" + PORT);

}

}

清单 2 中,首先创建一个org.apache.mina.transport.socket.nio.NioSocketAcceptor 的实例,由它提供I/O 服务;接着获得该I/O 服务的过滤器链,并添加两个新的过滤器,一个用来记录相关日志,另外一个用来在字节流和文本之间进行转换;最后配置I/O 处理器。完成这些之后,通过bind 方法来在特定的端口进行监听,接收连接。服务器启动之后,可以通过操作系统自带的Telnet 工具来进行测试,如图2 所示。在输入表达式之后,计算结果

会出现在下面一行。

上一节中给出了一个简单的基于 Apache MINA 的网络应用的实现,可以用来熟悉基本的架构。而在实际开发中,网络应用都是有一定复杂度的。下面会以一个比较复杂的联机游戏作为示例来详细介绍 Apache MINA 的概念、API 和典型用法。

该联机游戏支持两个人进行俄罗斯方块的对战。这个游戏借鉴了 QQ 的“火拼俄罗斯”。用户在启动客户端之后,需要输入一个昵称进行注册。用户可以在“游戏大厅”中查看当前已注册的所有其它用户。当前用户可以选择另外的一个用户发送游戏邀请。邀请被接受之后就可以开始进行对战。在游戏过程中,当前用户可以看到对方的游戏状态,即方块的情况。该游戏的运行效果如图 3所示。

下面开始以这个应用为例来具体介绍 Apache MINA 中的基本概念。先从 I/O 服务开始。

I/O 服务用来执行真正的 I/O 操作,以及管理 I/O 会话。根据所使用的数据传输方式的不同,有不同的 I/O 服务的实现。由于 I/O 服务执行的是输入和输出两种操作,实际上有两种具体的子类型。一种称为“I/O 接受器(I/O acceptor)”,用来接受连接,一般用在服务器的实现中;另外一种称为“I/O 连接器(I/O connector)”,用来发起连接,一般用在客户端的实现中。对应在Apache MINA 中的实现,org.apache.mina.core.service.IoService是 I/O 服务的接口,而继承自它的接口

org.apache.mina.core.service.IoAcceptor 和 org.apache.mina.core.servi ce.IoConnector 则分别表示 I/O 接受器和 I/O 连接器。IoService 接口提供的重要方法如表 1所示。

方法说明

setHandler(IoHandler handler) 设置 I/O 处理器。该 I/O 处理器会负责处理该 I/O 服务所管理产生的 I/O 事件。

getFilterChain() 获取 I/O 过滤器链,可以对 I/O 过滤器进行管理,包括添加和删getManagedSessions() 获取该 I/O 服务所管理的 I/O 会话。

下面具体介绍 I/O 接受器和 I/O 连接器。

I/O 接受器用来接受连接,与对等体(客户端)进行通讯,并发出相应的 I/O 事

件交给 I/O 处理器来处理。使用 I/O 接受器的时候,只需要调用 bind方法并

指定要监听的套接字地址。当不再接受连接的时候,调用 unbind停止监听即可。

关于 I/O 接受器的具体用法,可以参考清单 2中给出的计算器服务的实现。

I/O 连接器用来发起连接,与对等体(服务器)进行通讯,并发出相应的 I/O 事

件交给 I/O 处理器来处理。使用 I/O 连接器的时候,只需要调用 connect方

法连接指定的套接字地址。另外可以通过 setConnectTimeoutMillis设置连接

超时时间(毫秒数)。

清单 3中给出了使用 I/O 连接器的一个示例。

SocketConnector connector = new NioSocketConnector();

connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);

connector.getFilterChain().addLast("logger", new LoggingFilter());

connector.getFilterChain().addLast("protocol",

new ProtocolCodecFilter(new TetrisCodecFactory()));

ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host, port)); connectFuture.awaitUninterruptibly();

回页首

在清单 3中,首先创建一个 Java NIO 的套接字连接

器 NioSocketConnector 的实例,接着设置超时时间。再添加了 I/O 过滤器之后,通过 connect 方法连接到指定的地址和端口即可。

在介绍完 I/O 服务之后,下面介绍 I/O 会话。

I/O 会话表示一个活动的网络连接,与所使用的传输方式无关。I/O 会话可以用

来存储用户自定义的与应用相关的属性。这些属性通常用来保存应用的状态信息,

还可以用来在 I/O 过滤器和 I/O 处理器之间交换数据。I/O 会话在作用上类似

于 Servlet 规范中的 HTTP 会话。

Apache MINA 中 I/O 会话实现的接口

是 org.apache.mina.core.session.IoSession 。该接口中比较重要的方法如 表

2 所示。

方法 说明

close(boolean immediately) 关闭当前连接。如果参数 immediately 为 true 的话,连接会等到队发送请求都完成之后才关闭;否则的话就立即关闭。

getAttribute(Object key) 从 I/O 会话中获取键为 key 的用户自定义的属性。

setAttribute(Object key, Object value)

将键为 key ,值为 value 的用户自定义的属性存储到 I/O 会话中。removeAttribute(Object key)

从 I/O 会话中删除键为 key 的用户自定义的属性。 write(Object message) 将消息对象 message 发送到当前连接的对等体。该方法是异步的,当

到对等体的时候,IoHandler.messageSent(IoSession,Object)会被

话,也可以等消息真正发送出去之后再继续执行后续操作。

在介绍完 I/O 会话之后,下面介绍 I/O 过滤器。

回页首

Java程序员必须了解的20个lib库

Java程序员必须了解的20个lib库 一般一个经验丰富的开发者,一般都喜欢使用开源的第三方api库来进行开发,毕竟这样能够提高开发效率,并且能够简单快速的集成到项目中去,而不用花更多的时间去在重复造一些无用的轮子,多了解一些第三方库可以提高我们的开发效率,下面就来看一下在开发过程中经常会用到的一些开发第三方库,也可能不是太全,就列举一些常见或者常用的吧。 1,日志库 日志库是最常用的,毕竟在开发项目的过程中都需要使用日志来记录项目的运行信息,从而很快的定位项目的发生的问题。尽管JDK附带了自己的日志库,但是还有更好的选择,例如Log4j、SLF4j和LogBack。一般建议使用SLF4j。比如Alibaba开发手册上也是这样说的,毕竟SLF4J使您的代码独立于任何特定的日志API,就是在项目的其它框架中使用了其它的日志框架库也能够很好的集成。 2,JSON转换库 在当今的web服务、手机api接口开发和物联网世界中,JSON已经成为将信息从客户端传送到服务器的首选协议。它们前端要学好必须每天坚持学习。为了方便大家的交流学习,也是创建了一个群每天都有分享学习方法和专业老师直播

前端课程,这个扣裙首先是132 中间是667 最后是127 前端学习零基础想要学习的同学欢迎加入,如果只是凑热闹就不要来了!!!已经取代了XML,成为以独立于平台的方式传输信息的首选方式。不幸的是,JDK没有JSON库。但是,有许多优秀的第三方库允许您解析和创建JSON消息,比如Jackson和Gson,FastJson。 3,单元测试库库 单元测试是区分普通开发人员和优秀开发人员的最重要的东西。程序员经常被给予不写单元测试的借口,但是最常见的避免单元测试的借口是缺乏流行的单元测试库的经验和知识,包括JUnit、Mockito和PowerMock。 4,通用类库 Java开发人员可以使用一些优秀的通用第三方库,比如Apache Commons和谷歌Guava。我总是在我的项目中包含这些库,因为它们简化了许多任务。正如约书亚?布洛赫(Joshua Bloch)在《Effective Java》一书中正确指出的那样,重新发明轮子是没有意义的。我们应该使用经过测试的库,而不是时不时地编写我们自己的程序。对于开发人员来说,熟悉Apache Commons和谷歌Guava 是很有用的。 5,HTTP库

史上最全Java基础知识点归纳

史上最全Java基础知识点归纳 写这篇文章的目的是想总结一下自己这么多年来使用Java的一些心得体会,主要是和一些Java基础知识点相关的,所以也希望能分享给刚刚入门的Java 程序员和打算入Java开发这个行当的准新手们,希望可以给大家一些经验,能让大家更好学习和使用Java。 这次介绍的主要内容是和J2SE相关的部分,另外,会在以后再介绍些J2EE 相关的、和Java中各个框架相关的内容。 经过这么多年的Java开发,以及结合平时面试Java开发者的一些经验,我觉得对于J2SE方面主要就是要掌握以下的一些内容。 1.JVM相关(包括了各个版本的特性) 对于刚刚接触Java的人来说,JVM相关的知识不一定需要理解很深,对此里面的概念有一些简单的了解即可。不过对于一个有着3年以上Java经验的资

深开发者来说,不会JVM几乎是不可接受的。 JVM作为Java运行的基础,很难相信对于JVM一点都不了解的人可以把Java语言吃得很透。我在面试有超过3年Java经验的开发者的时候,JVM几乎就是一个必问的问题了。当然JVM不是唯一决定技术能力好坏的面试问题,但是可以佐证Java开发能力的高低。 在JVM这个大类中,我认为需要掌握的知识有: JVM内存模型和结构 GC原理,性能调优 调优:Thread Dump,分析内存结构 class二进制字节码结构,class loader体系,class加载过程,实例创建过程 方法执行过程 Java各个大版本更新提供的新特性(需要简单了解) 2.Java的运行(基础必备) 这条可能出看很简单,Java程序的运行谁不会呢?不过很多时候,我们只是单纯通过IDE去执行Java程序,底层IDE又是如何执行Java程序呢?很多人并不了解。

Mina2源码分析

Mina2.0框架源码剖析(一) 整个框架最核心的几个包是:org.apache.mina.core.service, org.apache.mina.core.session, org.apache.mina.core.polling以及 org.apache.mina.transport.socket。 这一篇先来看org.apache.mina.core.service。第一个要说的接口是IoService,它是所有IoAcceptor和IoConnector的基接口.对于一个IoService,有哪些信息需要我们关注呢?1)底层的元数据信息TransportMetadata,比如底层的网络服务提供者(NIO,ARP,RXTX等),2)通过这个服务创建一个新会话时,新会话的默认配置IoSessionConfig。3)此服务所管理的所有会话。4)与这个服务相关所产生的事件所对应的监听者(IoServiceListener)。5)处理这个服务所管理的所有连接的处理器(IoHandler)。6)每个会话都有一个过滤器链(IoFilterChain),每个过滤器链通过其对应的IoFilterChainBuilder来负责构建。7)由于此服务管理了一系列会话,因此可以通过广播的方式向所有会话发送消息,返回结果是一个WriteFuture集,后者是一种表示未来预期结果的数据结构。8)服务创建的会话(IoSession)相关的数据通过IoSessionDataStructureFactory来提供。9)发送消息时有一个写缓冲队列。10)服务的闲置状态有三种:读端空闲,写端空闲,双端空闲。11)还提供服务的一些统计信息,比如时间,数据量等。 IoService这个服务是对于服务器端的接受连接和客户端发起连接这两种行为的抽象。 再来从服务器看起,IoAcceptor是IoService 的子接口,它用于绑定到指定的ip和端口,从而接收来自客户端的连接请求,同时会fire相应的客户端连接成功接收/取消/失败等事件给自己的IoHandle去处理。当服务器端的Accpetor从早先绑定的ip和端口上取消绑定时,默认是所有的客户端会话会被关闭,这种情况一般出现在服务器挂掉了,则客户端收到连接关闭的提示。这个接口最重要的两个方法是bind()和unbind(),当这两个方法被调用时,服务端的连接接受线程就启动或关闭了。 再来看一看客户端的连接发起者接口IoConnector,它的功能和IoAcceptor基本对应的,它用于尝试连接到服务器指定的ip和端口,同时会fire相应的客户端连接事件给自己的IoHandle去处理。当connet方法被调用后用于连接服务器端的线程就启动了,而当所有的连接尝试都结束时线程就停止。尝试连接的超时时间可以自行设置。Connect方法返回的结果是ConnectFuture,这和前面说的WriteFuture类似,在后面会有一篇专门讲这个模式的应用。 前面的IoAcceptor和IoConnector就好比是两个负责握手的仆人,而真正代表会话的实际I/O操作的接口是IoProcessor,它对现有的Reactor模式架构的Java NIO框架继续做了一层封装。它的泛型参数指明了它能处理的会话类型。接口中最重要的几个方法,add用于将指定会话加入到此Processor中,让它负责处理与此会话相关的所有I/O操作。由于写操作会有一个写请求队列,flush就用于对指定会话的写请求队列进行强制刷数据。remove方法用于从此Processor中移除和关闭指定会话,

JAVA NIO基础知识总结二_2012-1-9

JA V A NIO基础知识总结二 (一)、回顾一下总结一: (1)、NIO的几个概念: ①、Buffer :内存块,实质就是一个数组。NIO数据读或写得中转地。 ②、Channel:连接设备的通道。用于向buffer提供数据或者读取数据,异步I/O支持。 ③、Selector :channel事件的监听者,他能检测到一个或多个通道,并将事件分发出去 ④、SelectionKey:channel上发生的事件,包含了事件的状态信息和时间以及对应的channel。 (2)、在前面总结一中,最后的时候给出了一个完整的关于NIO操作网络套接字的例子,在这里先总结一下构建基于NIO的服务端的一般步骤:①、构造一个Selector ②、打开一个serverSocketChannel ③、设定serverSocketChannel为非阻塞 ④、绑定socketserverChannel到一个主机地址和端口 ⑤、注册selector并告知感兴趣的事情 (3)、Channel的状态有四种: ①、Connectable:当一个Channel完成socket连接操作已完成或者已失败。

②、Acceptable:当一个Channel已准备好接受一个新的socket连接时,channel是Acceptale ③、Readable:当一个channel能被读时。 ④、Writable:当一个Channel能被写时为可写状态。 (4)、下面是NIO中的关系图,来自于《java编程思想》

(二)、基于多线程的NIO 总结一的例子,是基于单线程的,单线程的好处是简单,不用去考虑过于复杂的线程问题,但是仔细想一下,如果数据在网络传输的过程中发生了阻塞呢,那岂不是要花费很多的时间?再者如果我们要实现像QQ中的聊天室呢,如何实现呢?。为了解决这些问题,我们现在试着采用多线程的,但是采用多线程,会产生很多线程,创建、销毁线程都是要花费时间的,所以这里可以运用到线程池来管理。 下面一个例子是:客户端发来信息,服务端然后转发所有的信息给在线的客户端。import java.io.IOException; import https://www.doczj.com/doc/8f13432251.html,.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; public class RSocketServer implements Runnable { private final static int POOLSIZE = 100;// 处理线程池的大小 private SelectionKey selectionKey; // 选择键 private ExecutorService service = Executors.newFixedThreadPool(POOLSIZE);// 固定大小的线程池 private boolean isRunning = true; private Selector selector;// 选择器 private String writeMsg;// 需要写的信息 private ServerSocketChannel ssc; public RSocketServer() { try { selector = Selector.open(); ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(8080)); selectionKey = ssc.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务器启动成功!正在端口为8080上等待..."); } catch (Exception e) { e.printStackTrace(); } } public void run() { try {

mina 框架学习

mina 框架学习 转帖:https://www.doczj.com/doc/8f13432251.html,/s/blog_5f9beca40101ee6w.html 1、简介 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP 协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。Apache Mina也称为: l NIO框架 l客户端/服务端框架(典型的C/S架构) l 网络套接字(networking socket)类库 2、通信流程 那么让我们来看一下mina在我们应用中处于什么样的一个位置呢 上图可以看出mina位于应用程序和底层网络传输之间,它不关心底层网络数据如何传输,只负责接收底层数据,过滤并转换为Java对象提供给我们的应用程序,然后把应用程序响应值过滤并转换为底层识别的字节,提供给底层传输。 再来看一下mina 通信流程图

可以很清晰看出mina主要有三个主要的业务接口:IoService,IoFilter和IoHandler (1) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监听是否有连接被建立。 (2) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与decode 是最为重要的、也是你在使用Mina 时最主要关注的地方。 (3) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。 总的来说创建一个基于mina框架的应用分为三个模块: 创建连接(IoService))——>添加消息过滤器(IoFilter)——>添加业务处理(IoHandler) 3、server 和client mina中server和client没有多大区别都是通过Ioservice建立连接和通信的,来看下具体流程 Server 一般地,服务端会有一个端口来监听client的请求/packet,并且为每隔connect建立一个session(无论是基于TCP/IP协议还是UDP协议),Server端主要通过IoAccptor建立连接

MINA网络通信框架

MINA网络通信框架 Posted by kunshuo on 2012-04-11Leave a comment (1)Go to comments MINA网络通信框架 基本介绍: Apache MINA 2是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。它提供了一个抽象的事件驱动的异步API,可以使用TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。Apache MINA 2可以作为开发网络应用程序的一个良好基础。 Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、 接收的数据以及你的业务逻辑即可。 mina的基本架构: 在图中的模块链中,IoService 便是应用程序的入口,相当于我们前面代码中的IoAccepter,IoAccepter 便是IoService 的一个扩展接口。

IoService 接口可以用来添加多个IoFilter,这些IoFilter 符合责任链模式并由IoProcessor 线程负责调用。而IoAccepter 在ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。ioHandler则为应用逻辑处理类。 主要类以及接口: (1.)IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监 听是否有连接被建立。 (2.)IoProcessor:这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是 说它也拥有自己的Selector,这是与我们使用JAVA NIO编码时的一个不同之处, 通常在JAVA NIO编码中,我们都是使用一个Selector,也就是不区分IoService 与IoProcessor两个功能接口。另外,IoProcessor负责调用注册在IoService上 的过滤器,并在过滤器链之后调用IoHandler。 (3.)IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、 数据的编码(write方向)与解码(read方向)等功能,其中数据的encode 与decode 是最为重要的、也是你在使用Mina时最主要关注的地方。

网络编程框架

网络编程框架 Socket编程接口 NIO编程接口 Leader Follower 原理SEDA原理 Netty编程框架 Mina编程框架 Web编程框架 分布式应用 ?负载均衡器/Load Balancer Session Stickiness ?内存状态复制/Replication Sysch-replication Asych-replication ?Local Cache

ConcurrentHashMap FastMap Local Queue Queues Queues类似于沟通“生产者”和“消费者”的管道。组件从管道的一端放入,然后从另一端取出:“先进先出”(FIFO)的顺序。Queue接口在JavaSE5新添加到java.util中的,能够被用于单线程访问的场景中,主要适用于多个生产者、一个或多个消费者的情景,所有的读写操作都是基于同一个队列。 java.util.concurrent包中的BlockingQueue接口是Queue的子接口,而且还添加了新的特性处理如下场景:队列满(此时刚好有一个生产者要加入一个新的组件)、队列空(此时刚好有一个消费者读取或者删除一个组件)。BlockingQueue提供如下方案解决这些情况:一直阻塞等待直到其他线程修改队列的数据状态;阻塞一段时间之后返回,如果在这段时间内有其他线程修改队列数据,那么也会返回。

Deque 在JavaSE6中新增加了两端都可以添加和删除的队列-Deque (发音 "deck",not "dick"). Deques不仅可以从一端添加元素,从另一端移除,而且两端都可以添加和删除元素。如同BlockingQueue,BlockingDeque接口也为阻塞等待和超时等待的特殊情况提供了解决方法。因为Deque继承Queue、BlockingDeque继 Deque的一个特殊应用场景是只在一个端口进行添加、删除、检查操作--堆栈(first-in-last-out顺序)。Deque接口提供了stack相同的方法:push(), pop()和peek(),这方法和addFirst(), removeFirst(), peekFirst()一一对应,可以把Deque的任何一个实现类当做堆栈使用。表6中是JDK中Deque和BlockingDeque的实现。注意Deque继承Queue,BlockingDeque继承自BlockingQueue。 分布式缓存 Coherence Jboss Cache Mem Cache 分布式数据存储 数据库的垂直划分和水平划分

关于Apache Mina

关于Apache Mina 一、介绍 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架。通过使用MINA框架可以可以省下处理底层I/O和线程并发等复杂工作,开发人员能够把更多的精力投入到业务设计和开发当中。MINA框架的应用比较广泛,应用的开源项目有Apache Directory、AsyncWeb、Apache Qpid、QuickFIX/J、Openfire、SubEthaSTMP、red5等。 MINA框架的特点有:基于java NIO类库开发;采用非阻塞方式的异步传输;事件驱动;支持批量数据传输;支持TCP、UDP协议;控制反转的设计模式(支持Spring);采用优雅的松耦合架构;可灵活的加载过滤器机制;单元测试更容易实现;可自定义线程的数量,以提高运行于多处理器上的性能;采用回调的方式完成调用,线程的使用更容易。 二、调用过程 在图中的模块链中,IoService 便是应用程序的入口,相当于代码中的 IoAccepter,IoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来添加多个 IoFilter,这些 IoFilter 符合责任链模式并由 IoProcessor 线程负责调用。而 IoAccepter 在 ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。 在上图中最右端也就是 IoHandler,这便是业务处理模块。在业务处理类中不需要去关心实际的通讯细节,只管处理客户端传输过来的信息即可。编写 Handler 类就是使用 MINA 开发网络应用程序的重心所在,相当于 MINA 已经帮你处理了所有的通讯方面的细节问题。为了简化 Handler 类,MINA 提供了 IoHandlerAdapter 类,此类仅仅是实现了 IoHandler 接口,但并不做任何处理。 IoHandler 接口中具有如下一些方法: Java代码 1.public interface IoHandler { 2. void sessionCreated(IoSession session) throws Exception;//会话创建 3. void sessionOpened(IoSession session) throws Exception;//打开会话,与 sessionCreated最大的区别是它是从另一个线程处调用的 4. void sessionClosed(IoSession session) throws Exception;//会话结束,当连接 关闭时被调用 5. void sessionIdle (IoSession session, IdleStatus status) throws Except ion;//会话空闲 6. void exceptionCaught(IoSession session, Throwable cause) throws Exceptio n;//异常捕获,Mina会自动关闭此连接

MINA框架新人指南

支付宝(中国)网络技术有限公司 蓝秋鹏(仲景)

目录 1.前言 (3) 2.实践 (4) 2.1.服务端演示 (4) 2.2.客户端演示 (6) 3.进阶 (8)

在资金线混有两个技术框架是一定要懂得如何使用的,它们就是MINA和HTTPCLIENT(还没听过的,就先百度一下)。支付宝和银行前置机之间的通讯基本都是使用者两种框架,即使你不懂SOCKET或者HTTP很底层的协议也没多大关系。 对于HTTPCLIENT有过很多实践了,从我刚进支付宝的第一个项目个人诚信通,到最近的建行境外收单直连改造,都是使用HTTP通讯。 突然间要做建行银行卡代扣,需要使用SOCKET跟建行通讯,对SOCKET 一点都不懂,只是听大禹和香石说使用MINA很简单,闭关修炼了两天确实很简单,哈哈。先找到MINA的主页,肯定有很多资料可以学习的,然后再编写DEMO,跑起来,改改DEMO,添加一些个性化的功能,两天时间基本上就算入门啦,可以开始进入项目编码啦。这些时间对于开发工程师来说,就是项目的技术准备阶段,在BRD或者PRD阶段投入的资源,让开发人员在开发阶段不再担心技术问题,可以快速编码,甚至提前完成开发任务。 跟MINA类似的框架,还有著名的Jboss Netty,代码框架非常类似,使用方法也大同小异,可以说Jboss Netty是MINA的改良版,但是目前我们系统还没有Jboss Netty的实际应用,不考虑引入到实际项目中。 本文档作为MINA框架的入门手册,浅显易懂,没有高级应用,比如配置线程模型,就可以满足日常开发。

跟银行的通讯,首先我们要定位自己的角色,我们扮演的是客户端,还是服务端,大部分场景我们都是扮演客户端的角色,如果银行有通知接口,在业务做完时银行会主动通知我们,推进我们的业务,这时我们就是服务端。 2.1.服务端演示 通过DEMO实现一个简单的服务端,MINA框架已经做了很好的封装,我们只需要编写几行代码,通过main启动MinaServer,监听端口1314: SOCKET接口是TCP/IP网络的API,不说这些很抽象的概念,我们可以直接使用MINA封装的SocketAcceptor 。 main方法中定义了整型的端口1314,在实际应用中一般通过antx.properties配置端口,这样就可以把配置的权限交给运维部门。 每一个信息都会通过在IoAcceptor中定义的过滤器链的所有过滤器,完成个性化的日志记录和解码工作。日志过滤器用SL4J库记录信息,而编码过滤器则解码所有收到的信息. 这个简单的例子,我们使用 new TextLineCodecFactory() 发送的信息进行编码,这是MINA自带的,功能有限,只能处理文本或者String类型。 还有一个参数new ServerHandler(),传的是实现IoHandler接口的类,对客户端的请求要进行什么业务处理,都在这里实现。

Java 远程通讯_MINA

第一章MINA前述 1.1线程模型 MINA线程模型采用了Reactors in threads模型,即Main Reactor + Sub Reactors的模式。由main reactor处理连接相关的任务:accept、connect等,当连接处理完毕并建立一个socket连接(称之为session)后,给每个session分配一个sub reactor,之后该session的所有IO、业务逻辑处理均交给了该sub reactor。每个reactor均是一个线程,sub reactor中只靠内核调度,没有任何通信且互不打扰。 现在来讲讲我对线程模型演进的一些理解: Thread per Connection:在没有nio之前,这是传统的java网络编程方案所采用的线程模型。即有一个主循环,socket.accept阻塞等待,当建立连接后,创建新的线程/从线程池中取一个,把该socket连接交由新线程全权处理。这种方案优缺点都很明显,优点即实现简单,缺点则是方案的伸缩性受到线程数的限制。 Reactor in Single Thread:有了nio后,可以采用IO多路复用机制了。我们抽取出一个单线程版的reactor模型,时序图见下文,该方案只有一个线程,所有的socket连接均注册在了该reactor上,由一个线程全权负责所有的任务。它实现简单,且不受线程数的限制。这种方案受限于使用场景,仅适合于IO密集的应用,不太适合CPU密集的应用,且适合于CPU资源紧张的应用上。 Reactor + Thread Pool:方案2由于受限于使用场景,但为了可以更充分的使用CPU资源,抽取出一个逻辑处理线程池。reactor仅负责IO任务,线程池负责所有其它逻辑的处理。虽然该方案可以充分利用CPU资源,但是这个方案多了进出thread pool的两次上下文切换。

MINA 框架简介

MINA 框架简介 2011-02-12 9:35 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。Mina 主要有1.x 和2.x 两个分支,这里我们讲解最新版本2.0,如果你使用的是Mina 1.x,那么可能会有一些功能并不适用。学习本文档,需要你已掌握JAVA IO、JAVA NIO、JAVASocket、JAVA 线程及并发库(java.util.concurrent.*)的知识。Mina 同时提供了网络通信的Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中都处于如下的位置: 1。MINA 框架简介 当客户首次访问采用MINA编写的程序时,IoAcceptor作为线程运行,负责接受来自客户的请求。当有客户请求连接时,创建一个 Session,该Session与IoProcessor、SocketChannel以及IOService联系起来。IoProcessor也作为另外一个线程运行,定时检查客户是否有数据到来,并对客户请求进行处理,依次调用在IOService注册的各个IoFilter,最后调用 IoHandler进行最终的逻辑处理,再将处理后的结果Filter后返回给客户端。 2。IoSession Session可以理解为服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,指定服务器地址和端口,客户端也会指定或者根据网络路由信息自动指定一个地址、自动分配一个端口。这个地址、端口对构成一个Session。 Session是服务器端对这种连接的抽象,MINA对其进行了封装,定义了IoSession 接口,用来代表客户端与服务器的连接,在服务器端来指代客户端,实现对客户端的操作、绑定与客户端有关的信息与对象。通过利用Session的这个概念,编写程序时就可以在服务器端非常方便地区分出是当前处理的是哪个客户端的请求、维持客户端的状态信息、可以实现客户端之间相互通讯。 IoSession提供以下一些常用方法: (1)setAttribute(Object key, Object value) getAttribute(Object key)

ESB学习总结

一ESB概述 ESB是传统中间件技术与XML、WEB服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。ESB提供了一种开放的、基于标准的消息机制,通过简单的标准适配器和接口,来完成粗粒度应用和其他组件之间的互操作,能够满足大型异构企业环境的集成需求。它可以在不改变现有基础结构的情况下让几代技术实现互操作。 ESB就是一种可以提供可靠的、有保证的消息技术的最新方法。ESB中间件产品利用的是web服务标准和公认的可靠消息MOM协议接口(例如IBM的WebSphere MQ)。企业服务总线的概念是从面向服务体系架构SOA发展而来的。SOA描述了一种IT基础设施的应用集成模型,其中的软构件集是以一种定义清晰的层次化结构互相耦合,其中,每一个ESB 是一耳光预先组装的SOA实现,它包含了实现SOA分层目标所必需的基础功能部件。 ESB不是一个应用程序框架,也不是一个企业应用的解决方案,它只是一个基于消息的调用企业服务的通信模块。可以把它嵌入到应用程序框架中,例如嵌入到spring容器里面,或者嵌入到工作流系统中,它的作用是对企业里面的SOA服务的调用提供一个框架和简便的方法。 二SOA(Service Oriented Architecture) SOA本身就是一种面向企业级服务的系统架构,简单来说,SOA就是一种进行系统开发的新的体系架构,在基于SOA架构的系统中,具体应用程序的功能是由一些松耦合并且具有统一接口定义方式的组件(也就是service)组合构建起来的。它是一种以服务为基础的架构,服务边界清晰,服务自治,低耦合。它将应用分解为模块和可重用的函数以及服务,组合服务和模块以符合业务的需求,并重用现有的服务和模块以满足变化的业务需求。 三ESB和JBI JBI:Java Business Integration 一种ESB规范(Java领域) 定义了组件框架、组件描述、部署模型定义了归一化消息模型 定义了客户端API接口定义了管理模型(JMX) ESB是产品,JBI是一个Java领域的ESB规范 四ESB定义 它是面向服务框架的实现 它通常是操作系统和编程语无关的,它应能在Java和.Net应用程序之间工作 它使用XML作为标准通信语言 它支持Web服务标准 它支持消息传递(同步、异步、点对点、发布-订阅) 它包含基于标准的适配器,用于集成传统系统 它包含对服务编制(orchestration)和编排(choreography)的支持 它包含智能、基于内容的路由服务 它包含标准安全模型,用于ESB的认证、授权和审计 它包含转换服务(通常是使用XSLT),在发送应用和接收应用之间转换格式,简化数据格式和值的转换 它包含基于模式(schema)的验证,用于发送和接收消息 它可以统一应用业务规则,充实其它来源的消息,分拆和组合多个消息,以及处理异常它可以条件路由,或基于非集中策略的消息转换,即不需要集中规则引擎 它可以监视不同SLA(服务级别合约)的消息响应门限,以及在SLA中定义的其它特性它常常简化“服务类别”,向更高或更低优先级用户做出适当的响应

Socket网络框架 MINA

Socket网络框架MINA MINA是一个网络应用框架,在不牺牲性能和可扩展性的前提下用于解决如下问题: 1:快速开发自己的英勇。 2:高可维护性,高可复用性:网络I/O编码,消息的编/解码,业务逻辑互相分离。 3:相对容易的进行单元测试。 3.1 IoFilters: IoFilter为MINA的功能扩展提供了接口。它拦截所有的IO事件进行事件的预处理和后处理(AOP)。我们可以把它想象成 Servlet的filters。 IoFilter能够实现以下几种目的: 事件日志 性能检测 数据转换(e.g. SSL support),codec 防火墙…等等 3.2 codec: ProtocolCodecFactory MINA提供了方便的Protocol支持。如上说讲,codec在IoFilters中设置。通过它的Encoder和Decoder,可以方便的扩展并支持各种基于Socket 的网络协议,比如HTTP服务器、FTP服务器、Telnet服务器等等。 要实现自己的编码/解码器(codec)只需要实现interface: ProtocolCodecFactory即可. 在MINA 1.0版本,MINA已经实现了几个常用的(codec factory): DemuxingProtocolCodecFactory, NettyCodecFactory, ObjectSerializationCodecFactory, TextLineCodecFactory 其中:

TextLineCodecFactory: A ProtocolCodecFactory that performs encoding and decoding between a text line data and a Java string object. This codec is useful especially when you work with a text-based protocols such as SMTP and IMAP. ObjectSerializationCodecFactory: A ProtocolCodecFactory that serializes and deserializes Java objects. This codec is very useful when you have to prototype your application rapidly without any specific codec. DemuxingProtocolCodecFactory: A composite ProtocolCodecFactory that consists of multiple MessageEncoders and MessageDecoders. ProtocolEncoder and ProtocolDecoder this factory returns demultiplex incoming messages and buffers to appropriate MessageEncoders and MessageDecoders. NettyCodecFactory: A MINA ProtocolCodecFactory that provides encoder and decoder for Netty2 Messages and MessageRecognizers. 3.3 business logic: IoHandler MINA中,所有的业务逻辑都有实现了IoHandler的class完成interfaceHandles: all protocol events fired by MINA. There are 6 event handler methods, and they are all invoked by MINA automatically. 当事件发生时,将触发IoHandler中的方法: sessionCreated, sessionOpened, sessionClosed, sessionIdle, exceptionCaught, messageReceived, messageSent MINA 1.O中,IoHandler的实现类: ChainedIoHandler, DemuxingIoHandler, IoHandlerAdapter,

mina框架使用总结

MINA框架使用总结 简单介绍:MINA框架是对java的NIO包的一个封装,简化了NIO程序开发的难度,封装了很多底层的细节,然开发者把精力集中到业务逻辑上来,最近做了一个相关的项目,为了备忘对MINA做一个总结。 下面这个start方法用来初始化MINA: Java代码 1.private void start(int port, WebContext ctx) 2.throws IOException, InstantiationException 3. , IllegalAccessException, ClassNotFoundException { 4.//初始化Acceptor 5. NioSocketAcceptor acceptor = new NioSocketAcceptor(5); 6. 7. java.util.concurrent.Executor threadPool = Executors.newFixedThreadPool(150 0);//建立线程池 8.//加入过滤器(Filter)到Acceptor 9. acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool)); 10.acceptor.getFilterChain().addLast("codec", 11.new ProtocolCodecFilter(new WebDecoder(),new WebEncoder())); 12. LoggingFilter filter = new LoggingFilter(); 13. filter.setExceptionCaughtLogLevel(LogLevel.DEBUG); 14. filter.setMessageReceivedLogLevel(LogLevel.DEBUG); 15. filter.setMessageSentLogLevel(LogLevel.DEBUG); 16. filter.setSessionClosedLogLevel(LogLevel.DEBUG); 17. filter.setSessionCreatedLogLevel(LogLevel.DEBUG); 18. filter.setSessionIdleLogLevel(LogLevel.DEBUG); 19. filter.setSessionOpenedLogLevel(LogLevel.DEBUG); 20. acceptor.getFilterChain().addLast("logger", filter); 21. 22. acceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用 23. 24. acceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的 端口可以重用 25. acceptor.getSessionConfig().setReceiveBufferSize(1024);//设置输入缓冲区的大小 26. acceptor.getSessionConfig().setSendBufferSize(10240);//设置输出缓冲区的大小 27.//设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出 28. acceptor.getSessionConfig().setTcpNoDelay(true); 29.//设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来 将被服务器拒绝 30. acceptor.setBacklog(100);

Mina使用教程

Mina框架简介 一、Mina基本概念 1、BIO、NIO、AIO Java BIO :同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 使用API:ServerSocket、Socket Java NIO :同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 使用API:ServerSocketChannel、SocketChannel、Selector Java AIO(NIO.2) :异步通道提供支持连接、读取、以及写入之类非锁定操作的连接,并提供对已启动操作的控制机制。Java 7 中用于Java Platform(NIO.2)的More New I/O APIs,通过在 java.nio.channels 包中增加四个异步通道,从而增强了Java 1.4 中的New I/O APIs(NIO)。 使用API:AsynchronousServerSocketChannel、AsynchronousSocketChannel、CompletionHandler 2、NIO线程模型 单一线程单一Selector模型:

与多线程处理BIO相比减少了线程数量,用一个线程循环处理ACCEPT、READ、WRITE。但是如果某一次READ 或者WRITE处理时间过长,都会影响后面的事件响应。 3、Mina2.0的线程模型 与单一线程处理单一Selector相比,Mina采用三种线程:IoAcceptor/IoConnector线程、IoProcessor线程、 IoHandler线程 在服务器端,bind一个端口后,会创建一个Acceptor线程来负责监听工作。这个线程的工作只有一个:

相关主题
文本预览
相关文档 最新文档