首页 > OOP语言 > 其它 > 正文

使用 Apache MINA 2 开发网络应用
2012-03-28 00:00:00   来源:www.bianceng.cn   评论:0 点击:

暂时无描述信息

如 图 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 处理器由于是与具体的业务相关的,一般来说都是需要自己来实现的。

事件驱动的 API

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 所示。

清单 1. 计算器服务的 I/O 处理器 CalculatorHandler

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.");
    }
  }
}

相关热词搜索:

上一篇:使用Blueprint Container规范构建OSGi应用程序
下一篇:结合使用 Apache Geronimo 和 Lift

分享到: 收藏