1、先简单介绍下MINA:
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP
协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),
Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异
步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。
2.MINA框架的常用类类NioSocketAcceptor用于创建服务端监听;类NioSocketConnector用于创建客户端连接;类IoSession用来保存会话属性和发送消息;类IoHandlerAdapter用于定义业务逻辑,常用的方法有:方法
定义sessionCreated()当会话创建时被触发sessionOpened()当会话开始时被触发sessionClosed()当会话关闭时被触发sessionIdle()当会话空闲时被触发exceptionCaught()当接口中其他方法抛出异常未被捕获时触发此方法messageRecieved()当接收到消息后被触发messageSent()当发送消息后被触发
3、应用示例
所需jar包slf4j-api.jar、slf4j-jdk14.jar、MINA-core-2.0.0-M1.jar。相关包可到官方网站下载。
首先定义一个业务逻辑处理器TimeServerHandler,继承自IoHandlerAdapter,实现的功能有:当客户端创建会话时会显示客户端设备的IP和端口;当客户端输入quit时结束会话;客户端输入其它内容时则向客户端发送当前时间。代码如下:
publicclassTimeServerHandlerextendsIoHandlerAdapter {
@Override
publicvoidsessionCreated(IoSession session) {
// 显示客户端的ip和端口
System.out.println(session.getRemoteAddress().toString());
}
@Override
publicvoidmessageReceived(IoSession session, Object message)
throwsException {
String str = message.toString();
if(str.trim().equalsIgnoreCase("quit")) {
session.close();// 结束会话
return;
}
Date date = newDate();
session.write(date.toString());// 返回当前时间的字符串
System.out.println("Message written..."+ str);
}
}
定义一个类MinaTimeServer用来启动服务端:
publicclassMinaTimeServer {
privatestaticfinalintPORT =9123;// 定义监听端口
privatestaticIoAcceptor acceptor;
publicstaticvoidmain(String[] args)throwsIOException {
acceptor = newNioSocketAcceptor();
acceptor.getFilterChain().addLast("logger",newLoggingFilter());
//acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));// 指定编码过滤器
acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory()));//支持中文
acceptor.setHandler(newTimeServerHandler());// 指定业务逻辑处理器
acceptor.setDefaultLocalAddress(newInetSocketAddress(PORT));// 设置端口号
acceptor.bind();// 启动监听
}
客户端:定义类TimeClientHandler来处理消息接收事件
publicclassTimeClientHandlerextendsIoHandlerAdapter {
publicTimeClientHandler() {
}
@Override
publicvoidmessageReceived(IoSession session, Object message)throwsException {
System.out.println(message);//显示接收到的消息
}
}
定义MinaTimeClient类用于连接服务端,并向服务端发送消息:
publicclassMinaTimeClient {
publicstaticvoidmain(String[] args) {
// 创建客户端连接器.
NioSocketConnector connector = newNioSocketConnector();
connector.getFilterChain().addLast( "logger",newLoggingFilter() );
//connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); //设置编码过滤器
connector.getFilterChain().addLast( "codec",newProtocolCodecFilter(newTextLineCodecFactory()));
connector.setConnectTimeout(30);
connector.setHandler(newTimeClientHandler());//设置事件处理器
ConnectFuture cf = connector.connect(newInetSocketAddress("127.0.0.1",9123));//建立连接
cf.awaitUninterruptibly();//等待连接创建完成
cf.getSession().write("hello");//发送消息
cf.getSession().write("quit");//发送消息
cf.getSession().getCloseFuture().awaitUninterruptibly();//等待连接断开
connector.dispose();
}
}
运行服务端server,再启动客户端MinaTimeClient,可看到进行通讯信息交互。
另在MinaTimeServer类中增加下面方法进行客户端连接总数以及服务端主动向客户端发送信息等测试。
publicstaticvoidstartMinaServer(){
acceptor = newNioSocketAcceptor();
acceptor.getFilterChain().addLast("logger",newLoggingFilter());
//acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));// 指定编码过滤器
acceptor.getFilterChain().addLast("codec",newProtocolCodecFilter(newTextLineCodecFactory()));//支持中文
acceptor.setHandler(newTimeServerHandler());// 指定业务逻辑处理器
acceptor.setDefaultLocalAddress(newInetSocketAddress(PORT));// 设置端口号
try{
acceptor.bind();
} catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// 启动监听
}
/**
* 获得客户端连接总数
* @return
*/
publicstaticintgetConNum(){
intnum = acceptor.getManagedSessionCount();
System.out.println("num:"+ num);
returnnum;
}
/**
* 向每个客户端发送消息
* @return
*/
publicstaticvoidsendConMessage(){
IoSession session;
Map conMap = acceptor.getManagedSessions();
Iterator iter = conMap.keySet().iterator();
while(iter.hasNext()) {
Object key = iter.next();
session = (IoSession)conMap.get(key);
session.write(""+ key.toString());
}
}