一 前言
java mina 是一个网络应用架构,屏蔽了socket通信与数据读写的细节,让我们只关心数据处理。
二 架构
下面是一个实现计算程序的小例子,client向服务器端发送一个表达式,服务端向客户端返回计算结果。
// 启动服务器
public class CalculatorServer {
private static final int PORT = 10010;
private static final Logger LOGGER = LoggerFactory
.getLogger(CalculatorServer.class);
public static void main(String[] args) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"))));
// 将收到的请求交给“I/O”处理器处理
acceptor.setHandler(new CalculatorHandler());
acceptor.bind(new InetSocketAddress(PORT));
LOGGER.info("计算器服务已启动,端口是" + PORT);
}
}
实际负责处理的数据的handler(即上图中的I/O处理器)
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.");
}
}
}
传统的socket通信,其实代码的模式相当固定化
- 创建socket(建立连接)
- 获取输入输出流
- 数据的处理
而mina框架除了nio带来的优势外,只让我们关心一件事,数据处理,就像上面的messageReceived方法,我们只需在这里写我们的处理逻辑就行了。