在上一篇文档中我们已经了解了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的作用就讲述完了,希望对你能有所帮助。:)
分享到:
相关推荐
深入理解Apache_Mina_(3)----_与IoHandler相关的几个类 深入理解Apache_Mina_(4)----_IoFilter和IoHandler的区别和联系 深入理解Apache_Mina_(5)----_配置Mina的线程模型 深入理解Apache_Mina_(6)----_Java_Nio_...
apache-mina-2.0.16-bin.zip;apache-mina-2.0.16.zip
apache-mina-2.0.4-src
apache-mina-2.0.7-bin.tar,apache-mina-2.0.7-src.tar,rxtx-2.0-7pre1-i386-pc-mingw32,rxtx-2.1-7r2
深入理解Apache_Mina_(1)----_Mina的几个类深入理解Apache_Mina_(1)----_Mina的几个类深入理解Apache_Mina_(1)----_Mina的几个类
apache-mina-2.0.16.zip
关于apache组织的mina通信框架,可替代 java.NIO.Selector 的更好选择, 里面包括 mina 2.07版本的源码,编译好的jar文件,以及一些网络上找来的网摘资料文档 [截至2013年10月止]。 打包文件名:...
apache-mina-2.0.4 架包 源码 学习教程.apache mina是Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序...
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...
apache-mina-2.0.7架包与源码(里面包含架包与源码)。
mina-core-2.0.1.jar,apache-mina-2.0.1
Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。 apache-mina-2.0.7-bin.zip,apache-mina-2.0.7-src.zip,log4j-1.2.17.zip,slf4j-api-1.6.6.jar,slf4j-api-1.6.6-...
最近一直在看 Mina 的源码...深刻的理解,关于 Mina 的基本知识的介绍,这里就不多说了,网上已经有很多不错的文 章 都对 Mina 做了较深刻的剖析,现在就是想从 Mina 的最根本的地方来对 Mina 做一些深层 次 上的探讨。
米娜 apache-mina-2.0.16-bin.zip米娜 apache-mina-2.0.16-bin.zip米娜 apache-mina-2.0.16-bin.zip米娜 apache-mina-2.0.16-bin.zip
apache-mina-2.0.4-bin
Apache 2008-02-19 发布了 MINA 2.0.0-M1,目前的最新版本
NULL 博文链接:https://chinaestone.iteye.com/blog/424568
Apache Mina中文参考手册 Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序
NULL 博文链接:https://chinaestone.iteye.com/blog/435929