一、Mina的网络应用架构
1.1 IO服务层
用来执行实际的 I/O操作,可支持TCP/IP UDP/IP 串口 虚拟机内部管道
1.2 IO过滤层
用来将I/O的字节流与对象和数据结构进行转换,通过AOP 实现数据处理。
1.3 IO处理器
用来执行具体的业务逻辑,大多数情况下使用已有事件,定义用户处理行为。
二、Mina事件驱动的Api
在Mina编程过程中,Mina将网络的各种活动抽象成事件,开发者可以处理其感兴趣的事件,不需要考虑底层的传输,只需要在IO处理器中处理抽象的I/O事件。
三、开发一个网络计算器
需求:通过TCP协议,服务器处理所有客户端的计算请求,之后返回给客户机。
服务器代码1:
//IO处理器
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 (ScriptExceptione) {
LOGGER.warn(e.getMessage(), e);
session.write("Wrong expression, try again.");
}
}
}
说明:
public void messageReceived(IoSession session,Object message)
该方法覆盖了IoHandlerAdapter
当这个处理器接收到新消息的时候,该方法就会被调用。
下面需要配置IO过滤器和IO处理器
代码2:
public classCalculatorServer {
private static final int PORT = 10010;
private static final Logger LOGGER =LoggerFactory.getLogger(CalculatorServer.class);
public static void main(String[] args) throwsIOException {
IoAcceptor acceptor =new NioSocketAcceptor(); //创建服务
acceptor.getFilterChain().addLast("logger", newLoggingFilter());//获取IO服务的过滤器链,添加日志过滤器
acceptor.getFilterChain().addLast( "codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8")))); //添加字节流和文本流的处理
acceptor.setHandler(newCalculatorHandler()); //设置处理器
acceptor.bind(newInetSocketAddress(PORT)); //绑定端口
LOGGER.info("计算器服务已启动,端口是" + PORT);
}
}
测试:通过Telnet 127.0.0.1:10010
输入 10X10可以得到100的输出结果