`

深入理解Apache Mina (3)---- 与IoHandler相关的几个类

阅读更多

在上一篇文档中我们已经了解了IoFilter的用法和其在Mina中的作用,作为Mina数据传输过程中比较重要的组件,IoFilter起到了承上启下的作用----接收数据,编/解码,将数据传递到逻辑层,当数据传递地到逻辑层时,IoFilter的使命就完成了,那么逻辑层的数据由谁来处理呢?如何处理的?这就是本文要讲述的内容----IoHandler。

 

在介绍IoFilter的时候,文中首先是从IoFilter的结构和其在Mina中的作用谈起的,最后添加了一个使用IoFilter的例子,之前我将其传给几个同学看时,感觉这种方式比较晦涩,应该将例子提到前面,由于时间的关系我不能在对IoFilter的介绍做过多的修改,所以在本篇文档中我就先以一个例子开头,介绍IoHandler,希望这种讲述方式能对你理解Mina有更多的帮助。

 

好了,言归正传,我们的例子还是以上篇文档中的IoFilter的例子为基础,在此基础上着重突出IoHandler的作用。

ServerMain:
public class ServerMain {
 public static void main(String[] args) throws IOException {
  SocketAddress address = new InetSocketAddress

("localhost", 4321);
  IoAcceptor acceptor = new SocketAcceptor();
  IoServiceConfig config = acceptor.getDefaultConfig

();

  // 配置数据的编解码器
  config.getFilterChain().addLast("codec",
    new ProtocolCodecFilter(new 

ObjectSerializationCodecFactory()));
  config.getFilterChain().addLast("logger", new 

LoggingFilter());
  
  // 绑定服务器端口
  acceptor.bind(address, new ServerHandler());
  System.out.println("  服务器开始在 8000 端口监听 

.......");
 }
} 
ServerHandler:
public class ServerHandler extends IoHandlerAdapter {
 // 创建会话
 public void sessionOpened(IoSession session) throws 

Exception {
  System.out.println("  服务器创建了会话  ");
  session.write("  服务器创建会话时发送的信息 。");
 }

 // 发送信息
 public void messageSent(IoSession session, Object message) 

throws Exception {
 }

 // 接收信息
 public void messageReceived(IoSession session, Object 

message)
   throws Exception {
 }
} 
ClientMain:
public class ClientMain {

 public static void main(String[] args) {
  SocketAddress address = new InetSocketAddress

("localhost", 4321);
  IoConnector connector = new SocketConnector();
  IoServiceConfig config = 

connector.getDefaultConfig();
 
  // 配置数据的编解码器
  config.getFilterChain().addLast("codec",
    new ProtocolCodecFilter(new 

ObjectSerializationCodecFactory()));
  config.getFilterChain().addLast("logger", new 

LoggingFilter());

  // 连接到服务器
  connector.connect(address, new ClientHandler());
  System.out.println(" 已经连接到了服务器 " + address);
 }
}
 
ClientHandler:
public class ClientHandler extends IoHandlerAdapter {

 // 发送信息
 public void messageSent(IoSession session, Object message) 

throws Exception {  
 }

 // 接收信息
 public void messageReceived(IoSession session, Object 

message)
   throws Exception {
  System.out.println("  客户端接收到的服务器的信息是  " 

+ message);
 }
} 

 

上面给出里这个例子中的主要的代码,当先后启动服务器和客户端后,服务器会在客户端连接到服务器后发送一个字符串的消息。这个消息的发送就是在IoHandler中发送的。IoHandler在Mina中属于业务层,这里的IoHandler更相是J2EE中的Servlet的作用,在IoHandler中你可以不用考虑底层数据的封装和转换,前提是你已经在IoFilter中已经完成了数据的转换。这里需要提到的一个是,所谓数据的转换,是指将二进制数据转换成Java中的可用对象或者是基本类型的数据。由于网络传输中传输的都是二进制数据,这就需要有一个专门的数据转换层,就Mina中的编解码器来实现这个功能。如果使用RMI,对于这个问题应该不陌生,二进制和对象之间的转化过程其实就是对象的序列化和反序列化的过程。关于Mina中实现对象的序列化和反序列化会在后续的文档中详细介绍,在此不在赘述。

 

既然IoHandler是逻辑层,我们就用IoHandler实现一个简单的逻辑实现。先听一个小故事:一个淘气的小孩要去KFC买汉堡,由于KFC生意比较好,人比较多,服务员忙不过来,于是KFC专门设立了一个自动售汉堡的机器,这个机器只是一个简单的数据收发装置,(由于汉堡的价格时常变化,所以价格会实时更新,因此该机器需要和KFC的汉堡的价格服务器相连)小朋友买汉堡时只要向机器中投入硬币,机器就会查询服务器,看价格是否符合,若符合,则送给小朋友一个汉堡

,若不符合则提示小朋友钱不够,买不到这个汉堡。

 

上面是我自己虚构的一个小故事,我们先不管现实中的KFC是如何运作的,我们就当故事是真的了,那么现在这个小的项目分配给了我们,我们需要抽象出它的需求:


客户端要向服务器发送数据,查询价格,根据价格是否合理给出相应的显示服务器接收客户度的价格查询请求,根据服务器中存储的价格信息,返回响应的结果。


根据上面的需求,我们使用Mina来实现上面的服务器和客户端,程序的代码如下(完整代码在附件中):

KFCFoodPriceHandler(服务器句柄):
public class KFCFoodPriceHandler extends IoHandlerAdapter {
 // 创建会话
 public void sessionOpened(IoSession session) throws 

Exception {
//  System.out.println("  服务器创建了会话  ");
 }

 // 接收信息
 public void messageReceived(IoSession session, Object 

message)
   throws Exception {
  HashMap<String, Object> map = (HashMap<String, 

Object>) message;
  String buythings = (String) map.get("购买");
//  System.out.println("  服务器接收到的信息 " + 

buythings);
  if (buythings.equals("汉堡")) {
   HashMap<String, Object> map2 = new 

HashMap<String, Object>();
   map2.put("食品", "汉堡");
   map2.put("价格", 4);
   session.write(map2);
  } else if (buythings.equals("鸡翅")) {
   HashMap<String, Object> map2 = new 

HashMap<String, Object>();
   map2.put("食品", "鸡翅");
   map2.put("价格", 5);
   session.write(map2);
  } else {
   session.write(" 该种物品已经出售完毕,谢谢

惠顾!");
  }
 }
}
 
KFCSellerHandler(客户端句柄):
public class KFCSellerHandler extends IoHandlerAdapter {

 private Integer childInputMoney_Ham = 4;
 private Integer childInputMoney_Chick = 5;
 // 创建会话
 public void sessionOpened(IoSession session) throws 

Exception {

  HashMap<String, Object> map = new 

HashMap<String, Object>();
  map.put("购买", "汉堡");
  session.write(map);
 }

 // 接收信息
 public void messageReceived(IoSession session, Object 

message)
   throws Exception {
//  System.out.println("  客户端接收到的服务器的信息是  "
//    + (HashMap<String, Object>) 

message);
  HashMap<String, Object> priceInfor = 

(HashMap<String, Object>) message;
//  System.out.println("============" + 

priceInfor.get("食品"));
  String foodName = (String) priceInfor.get("食品");
  if (foodName.equals("汉堡")) {
   Integer foodPrice = (Integer) priceInfor.get

("价格");
   if (foodPrice.equals

(childInputMoney_Ham)) {
    System.out.println("   您好,请收好

你的汉堡,欢迎下次光临!");
   } else {
    System.out.println("   对不起,你投

如的钱币数量不够,钱已经如数归还,请收好!");
   }
  } else if (foodName.equals("鸡翅")) {
   Integer foodPrice = (Integer) priceInfor.get

("价格");
   if (foodPrice.equals

(childInputMoney_Chick)) {
    System.out.println("   您好,请收好

你的汉堡,欢迎下次光临!");
   } else {
    System.out.println("   对不起,你投

如的钱币数量不够,钱已经如数归还,请收好!");
   }
  }
 }
} 

 

通过上面的程序我们可以看出Mina的中业务逻辑处理都可以在IoHandler中,而不需要考虑对象的序列化和反序列化问题。关于IoHandler的简单用法就说这么多。下面再看看与IoHandler相关的几个中要的类。

 

按照惯例,还是先给出IoHandler及其相关类的类图:

从上面的类图我们可以清晰的看到IoHandler是一个接口,它有两个子类:


IoHandlerAdpater:它只是提供了IoHandler中定义的方法体,没有任何的逻辑处理,你可以根据你自己的需求重写该类中的相关方法。这个类在实际的开发中使用的是较多的。我们上面写的例子都是继承于这个类来实现的。


SingleSessionIoHandlerDelegate:这是一个服务器和客户端只有一个会话时使用的类,在该类的方法中没有提供session的参数,该类在实际的开发中使用的较少,如果需要对该类进行更深入的了解,请参考Mina 1.1.7的API文档。

 

在Mina提供的IoHandler的具体实现中,大部分的实现类都是继承与IoHandlerApater,IoHandlerAdpater在Mina 1.1.7中的子类有三个:


ChainedIoHandler:这个类主要是用于处理IoHandler的messageReceived事件,它和IoHandlerChain配合使用。当在业务逻辑中有多个IoHandler需要处理时,你可以将你的每个IoHandler添加到IoHandlerChain中,这个和过滤器

链比较相似,关于IoFilter和IoHandlerChain的具体用法和区别会在后续的文档中给出。


StreamIoHandler:该类也是用于处理IoHandler的messageReceived事件,它主要用于文件传输的系统中,比如FTP服务器中,如果需要对该类进行更深入的了解,请参考Mina 1.1.7的API文档。


DemuxingIoHandler:该类主要是用于处理多个IoHandler的messageReceived,由于在TCP/IP协议的数据传输中会出现数据的截断现象(由于socket传输的数据包的长度是固定的,当数据包大于该长度,数据包就会被截断),所以提供这个类主要是保证IoHandler所处理的数据包的完整性,这个和编解码器中的CumulativeProtocolDecoder类似,关于这两个类的具体介绍会在后续的文档中给出。

 

至此,关于IoHandler的作用就讲述完了,希望对你能有所帮助。:)

分享到:
评论
3 楼 ChinaEstone 2009-11-10  
east_java 写道
LZ,你文章里面的类图是用什么画的啊?

netbeans中的UML插件。

不过现在我不用这个了,你可以试试JUDE最新版,个人感觉JUDE更好用。
2 楼 east_java 2009-11-10  
LZ,你文章里面的类图是用什么画的啊?
1 楼 ChinaEstone 2009-07-29  
附件中有本文的完整内容,欢迎下载!

相关推荐

    关于apache Mina Server

    深入理解Apache_Mina_(3)----_与IoHandler相关的几个类 深入理解Apache_Mina_(4)----_IoFilter和IoHandler的区别和联系 深入理解Apache_Mina_(5)----_配置Mina的线程模型 深入理解Apache_Mina_(6)----_Java_Nio_...

    深入理解Apache_Mina

    Apache Mina框架包括了几个核心组件,如IoAcceptor、IoHandler、IoSession和IoFilter。其中IoAcceptor负责监听端口并接受新的连接请求,IoHandler则是业务逻辑处理的核心,IoSession管理单个网络连接的生命周期,而...

    apache-mina-2.0.7

    使用Apache MINA时,你需要了解以下几个重要的概念: - **异步I/O**:MINA采用非阻塞I/O模型,允许多个连接并发处理,提高了系统性能和可伸缩性。 - **事件驱动**:MINA基于事件模型,当网络事件发生时(如数据到达...

    Apache-Mina-Server-2.0中文参考手册V1.0.docx

    Mina的通信结构由以下几个关键组件构成: 1. **IoService**:这是一个接口,通常表现为IoAcceptor或IoConnector,它们分别处理服务器端和客户端的连接。IoService在单独的线程上运行,利用Selector监听新的连接请求...

    Apache Mina 入门Demo

    在"Apache Mina 入门Demo"中,我们可以期待学习以下几个核心知识点: 1. **Mina架构**:Apache Mina的核心设计基于事件驱动和非阻塞I/O模型,这种模型特别适合处理大量并发连接。它将网络通信层抽象为一组服务,如...

    一个Apache MINA使用案例源代码ApacheMina

    Apache MINA是一个高性能、异步事件驱动的网络应用程序框架,主要设计用于简化开发服务器端的高性能...通过深入研究提供的源代码,你可以更深入地理解MINA的工作原理,并学习如何在Android应用中实现高效的网络通信。

    Apache_Mina.zip_apache_mina

    深入理解Apache Mina,我们需要掌握以下几点: 1. **Java NIO基础**:了解Java的非阻塞I/O模型,包括选择器(Selector)、通道(Channel)和缓冲区(Buffer)的概念。 2. **Mina架构**:理解Mina的事件驱动模型、...

    apache mina

    - Mina3_与IoHandler相关的几个类.pdf和Mina2_与IoFilter相关的几个类.pdf将深入探讨IoHandler和IoFilter的具体实现类及其功能。 - Mina4_IoFilter和IoHandler的区别和联系.pdf将对比分析两者的关系和用法。 - ...

    apache mina 简单示例

    在"apache mina 简单示例"中,我们通常会涉及以下几个关键概念: 1. **项目设置**:首先,你需要在你的开发环境中集成Apache Mina库。这可以通过在Maven或Gradle的依赖管理中添加Mina的相关依赖来实现。例如,在...

    Apache_Mina_Server_ 深入教程V1.0

    Mina Server的核心架构由几个关键组件构成,这些组件协同工作以实现高效可靠的网络通信: 1. **IoService**:负责套接字的建立和监听,每个IoService实例通常都有一个独立的Selector来监控连接状态。 2. **...

    mina源码+例子mina-2.0.0-M6.zip

    - **src** 目录:包含了MINA框架的源代码,通过阅读源代码,你可以深入理解MINA的设计思想和实现细节。 - **examples** 目录:包含了一系列示例项目,这些项目展示了如何使用MINA来创建不同类型的网络服务,如简单的...

    mina 源码

    在分析"apache-mina-2.0.4"源码时,我们可以深入理解其设计理念、架构以及核心组件。 1. **MINA的设计理念** MINA的核心理念是异步非阻塞I/O,它利用Java NIO(New I/O)库来实现高效的网络通信。通过非阻塞I/O,...

    深入理解Mina

    深入理解Mina还需要考虑几个关键的问题: 1. 为什么需要BaseIoService而不是仅使用IoService? BaseIoService的存在是为了提供IoService的默认实现,这样继承自BaseIoService的子类就不需要再实现所有IoService...

    apache mina 中文参考手册

    Mina 的核心架构由以下几个组件构成: 1. **IoService**:该接口负责管理 Socket 连接的建立和关闭,每个 IoService 对象都拥有自己的 Selector 用于监听连接请求。 2. **IoProcessor**:此接口负责监控数据在通道...

    Apache MINA框架所用的jar包

    在提供的压缩包文件中,包含以下几个关键的jar包: 1. **mina-core-2.0.0.jar**:这是Apache MINA的核心库,包含了所有用于创建和管理网络连接、处理I/O事件、编码和解码数据的基本组件。它支持NIO(非阻塞I/O)和...

    3本mina教程和mina帮助文档

    3. **Mina API**:熟悉Mina的主要类和接口,如`IoSession`、`IoHandler`、`IoFilter`等,并学会如何在项目中使用它们。 4. **过滤器**:掌握Mina的过滤器机制,理解如何自定义过滤器以实现数据的编码、解码、安全...

    Apache_Mina_Server中文参考手册.pdf

    Mina的核心API包括以下几个主要组件: 1. IoService:这是一个接口,负责在单个线程中建立套接字,并拥有自己的Selector来监听连接建立的情况。 2. IoProcessor:该接口在另一个线程中运行,负责检查通道上的数据...

Global site tag (gtag.js) - Google Analytics