Apache Mina实战
Mina介绍
Mina可以用于快速的开发基于网络通信的应用,特别是在开发手机端的游戏应用时,使用的较为普遍。本文简单介绍了一个用Mina搭建的一个简易讨论组,通过该应用可以对Mina的基本用法用途有个大致的了解。
界面效果
界面元素不多,使用了两个AWT组件。
客户端1:

客户端2:

服务端日志:

核心代码
服务端Handler
1: /**
2: * <服务端消息Handler>
3: *
4: * @author liping.action@gmail.com
5: * @version V1.0
6: */
7: public class ServerMessageHandler extends IoHandlerAdapter {
8: private MsgQueue msgQueueReceived;
9: private MsgQueue msgQueueSent;
10:
11: public MsgQueue getMsgQueueReceived() {
12: return msgQueueReceived;
13: }
14:
15: public void setMsgQueueReceived(MsgQueue msgQueueReceived) {
16: this.msgQueueReceived = msgQueueReceived;
17: }
18:
19: public MsgQueue getMsgQueueSent() {
20: return msgQueueSent;
21: }
22:
23: public void setMsgQueueSent(MsgQueue msgQueueSent) {
24: this.msgQueueSent = msgQueueSent;
25: }
26:
27: static {
28: PropertyConfigurator.configure(ClassLoader
29: .getSystemResource("log4j.properties"));
30: }
31: private static Logger logger = Logger.getLogger(ServerMessageHandler.class);
32:
33: @Override
34: public void exceptionCaught(IoSession session, Throwable cause)
35: throws Exception {
36: logger.error(cause.toString());
37: }
38:
39: @Override
40: public void messageReceived(IoSession session, Object message)
41: throws Exception {
42: Msg msg = (Msg) message;
43: logger.info("MSG:from=" + session.getRemoteAddress() + ",id="
44: + msg.getId() + ",content=" + msg.getContent());
45: Collection<IoSession> sessions = session.getService()
46: .getManagedSessions().values();
47: msg.setId(session.getRemoteAddress().toString());
48: for (IoSession ioSession : sessions) {
49: ioSession.write(msg);
50: }
51: }
52:
53: @Override
54: public void messageSent(IoSession session, Object message) throws Exception {
55: logger.info(Constant.MESSAGE_SENT);
56: }
57:
58: @Override
59: public void sessionClosed(IoSession session) throws Exception {
60: logger.info(Constant.SESSION_CLOSED);
61: }
62:
63: @Override
64: public void sessionCreated(IoSession session) throws Exception {
65: logger.info(Constant.SESSION_CREATED);
66: }
67:
68: @Override
69: public void sessionIdle(IoSession session, IdleStatus status)
70: throws Exception {
71: logger.info(Constant.SESSION_IDLE);
72: }
73:
74: @Override
75: public void sessionOpened(IoSession session) throws Exception {
76: logger.info(Constant.SESSION_OPENED);
77: logger.info("address : "
78: + session.getRemoteAddress());
79: }
80:
81: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }客户端handler
1: /**
2: * <客户端handler>
3: *
4: * @author liping.action@gmail.com
5: * @version V1.0
6: */
7: public class ClientMessageHanlder extends IoHandlerAdapter {
8: private static Logger logger = Logger.getLogger(ClientMessageHanlder.class);
9: private MsgModel msgModel;
10:
11: public MsgModel getMsgModel() {
12: return msgModel;
13: }
14:
15: public void setMsgModel(MsgModel msgModel) {
16: this.msgModel = msgModel;
17: }
18:
19: @Override
20: public void exceptionCaught(IoSession session, Throwable cause)
21: throws Exception {
22: super.exceptionCaught(session, cause);
23: }
24:
25: @Override
26: public void messageReceived(IoSession session, Object message)
27: throws Exception {
28: Msg msg = (Msg) message;
29: logger.info("msg:id=" + msg.getId() + ",content=" + msg.getContent());
30: msgModel.setMsg(msg);
31: msgModel.fireModelChange();//触发模型变更,通知观察者
32: }
33:
34: @Override
35: public void messageSent(IoSession session, Object message) throws Exception {
36: super.messageSent(session, message);
37: }
38:
39: @Override
40: public void sessionClosed(IoSession session) throws Exception {
41: super.sessionClosed(session);
42: }
43:
44: @Override
45: public void sessionCreated(IoSession session) throws Exception {
46: super.sessionCreated(session);
47: }
48:
49: @Override
50: public void sessionIdle(IoSession session, IdleStatus status)
51: throws Exception {
52: super.sessionIdle(session, status);
53: }
54:
55: @Override
56: public void sessionOpened(IoSession session) throws Exception {
57: Msg msg = new Msg(session.getRemoteAddress().toString(),
58: session.getLocalAddress() + " " + DateUtil.getCurrentData() + " 进入了讨论组!");
59: session.write(msg);
60: }
61: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }服务端启动器:
1: /**
2: * 服务端启动器
3: *
4: */
5: public class ServerLauncher {
6: static {
7: PropertyConfigurator.configure(ClassLoader
8: .getSystemResource("log4j.properties"));
9: }
10: private static Logger logger = Logger.getLogger(ServerMessageHandler.class);
11:
12: public static void main(String[] args) {
13: // 创建一个非阻塞的server端Socket ,用NIO
14: SocketAcceptor acceptor = new NioSocketAcceptor();
15: // 创建接收数据的过滤器
16: DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
17: // 设定这个过滤器将以对象为单位读取数据
18: ProtocolCodecFilter filter = new ProtocolCodecFilter(
19: new ObjectSerializationCodecFactory());
20: chain.addLast("objectFilter", filter);
21: // 设定服务器消息处理器
22: acceptor.setHandler(new ServerMessageHandler());
23: // 服务器绑定的端口
24: int bindPort = 9988;
25: // 绑定端口,启动服务器
26: try {
27: acceptor.bind(new InetSocketAddress(bindPort));
28: } catch (IOException e) {
29: logger.error(e.toString());
30: }
31: logger.info("Mina Server run done! on port:" + bindPort);
32: }
33: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
客户端启动器:
1: /**
2: * 客户端启动器
3: *
4: */
5: public class ClientLauncher {
6: static {
7: PropertyConfigurator.configure(ClassLoader
8: .getSystemResource("log4j.properties"));
9: }
10:
11: public static void main(String[] args) {
12: // 创建消息模型(被观察者)
13: MsgModel model = new MsgModel();
14: // 创建一个tcp/ip 连接
15: NioSocketConnector connector = new NioSocketConnector();
16: /*---------接收对象---------*/
17: // 创建接收数据的过滤器
18: DefaultIoFilterChainBuilder chain = connector.getFilterChain();
19: // 设定这个过滤器将以对象为单位读取数据
20: ProtocolCodecFilter filter = new ProtocolCodecFilter(
21: new ObjectSerializationCodecFactory());
22: chain.addLast("objectFilter", filter);
23: ClientMessageHanlder hanlder = new ClientMessageHanlder();
24: hanlder.setMsgModel(model);
25: // 设定客户端端的消息处理器
26: connector.setHandler(hanlder);
27: // Set connect timeout.
28: connector.setConnectTimeoutCheckInterval(30);
29: // 连结到服务器:
30: final ConnectFuture cf = connector.connect(new InetSocketAddress(
31: "127.0.0.1", 9988));
32: createComponent(model, cf);
33: cf.awaitUninterruptibly();
34: cf.getSession().getCloseFuture().awaitUninterruptibly();
35: connector.dispose();
36: }
37:
38: private static void createComponent(MsgModel model, final ConnectFuture cf) {
39: JFrame frame = new JFrame("Client");
40: frame.setLocation(450, 300);
41: final TextField textField = new TextField();
42:
43: textField.addKeyListener(new KeyListener() {
44: public void keyTyped(KeyEvent arg0) {
45: }
46:
47: public void keyReleased(KeyEvent arg0) {
48: }
49:
50: public void keyPressed(KeyEvent arg0) {
51: if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
52: String value = textField.getText();
53: if (!value.equals("")) {
54: Msg msg = new Msg("0002", value);
55: cf.getSession().write(msg);
56: textField.setText("");
57: }
58: }
59: }
60: });
61: // 自定义TextArea
62: CusTextArea textArea = new CusTextArea();
63: model.addObserver(textArea);
64: frame.setSize(300, 450);
65: frame.setResizable(false);
66: frame.setBackground(Color.white);
67: frame.add(textField, BorderLayout.SOUTH);
68: frame.add(textArea, BorderLayout.NORTH);
69: frame.pack();
70: frame.setVisible(true);
71: frame.addWindowListener(new CloseHandler(cf.getSession()));
72: textField.requestFocus();
73: }
74: }
结语
该应用为一个简单的讨论组程序,可实现多人讨论,说白了是重复造轮子,但通过此应用可以对mima的用法及原理进行简单了解。程序还有其他代码没有贴上来,全部由三部分组成,服务端、客户端、公共组件。公共组件提供服务端、客户端公共使用的部分,如消息,消息队列,消息模型等。如需要程序源码,联系我的邮件获取。
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Apache Mina实战的更多相关文章
- Apache MiNa 实现多人聊天室
Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...
- Apache Mina(一)
原文链接:http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应 ...
- Apache MINA(一)
Apache MINA is a network application framework which helps users develop high performance and high s ...
- Apache Mina 入门实例
这个教程是介绍使用Mina搭建基础示例.这个教程内容是以创建一个时间服务器. 以下是这个教程需要准备的东西: MINA 2.0.7 Core JDK 1.5 或更高 SLF4J 1.3.0 或更高 L ...
- Apache Mina原理及典型例子分析
Apache Mina ,一个高性能 Java 异步并发网络通讯框架.利用 Mina 可以高效地完成以下任务: TCP/IP 和 UDP/IP 通讯 串口通讯 VM 间的管道通讯 SSL/TLS JX ...
- Apache Mina 2.x 框架+源码分析
源码下载 http://www.apache.org/dyn/closer.cgi/mina/mina/2.0.9/apache-mina-2.0.9-src.tar.gz 整体架构 核心过程(IoA ...
- Apache Mina开发手冊之四
Apache Mina开发手冊之四 作者:chszs,转载需注明. 博客主页:http://blog.csdn.net/chszs 一.Mina开发的主要步骤 1.创建一个实现了IoService接口 ...
- 网络通信框架Apache MINA
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...
- Apache Mina(二)
在mina的源码,整个框架最核心的几个包是 : org.apache.mina.core.service :IoService.IoProcessor.IoHandler.IoAcceptor.IoC ...
随机推荐
- Android-Gallery[使用C# And Java实现]
运行效果 C#实现 using Android.App; using Android.OS; using Android.Widget; namespace ImageDemo { [Activity ...
- CSS布局经典—圣杯布局与双飞翼布局
在我之前的博客网页整体布局完全剖析-剖完你不进来看一下么?中总结单列.两列.三列固宽与变宽布局,我还以为已经囊括了所有经典的网页布局方法了呢,当然除了CSS3的弹性盒模型没有涉及到,现在看来确实是自己 ...
- Arduino uno 引脚说明
http://openhome.cc/Gossip/Books/mBlockArduino1-3and1-4.html http://swf.com.tw/?p=406
- #英文#品读中国城市个性——最好的和最坏的&当东方遇到西方
冒险家的乐园 a playground of risk 实现发财梦 realize one's dreams of wealth 道德沦丧,堕落 moral deprivation 租界 foreig ...
- javascript闭包函数
JavaScript中的匿名函数及函数的闭包 1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...
- 小规模的流处理框架.Part 1: thread pools
原文链接:http://ifeve.com/part-1-thread-pools/ 很不错的一篇文章
- 学习微信小程序之css6
- winform进程、线程、TreeView递归加载
进程: 一般来说,一个程序就是一个进程,不过也有一个程序需要多个进程支持的情况. 进程所使用的类:Process 所需命名空间:System.Diagnostics; 可以通过进行来开启计算机上现有的 ...
- Java Web 项目目录规范
一.项目结构 这里和其他项目区别不大,我将模板抽离出来,更容易分析和理解: 解释一下:js主要包括extends(引入第三方的js).module(项目模块自己的js).lib(引用包,这里也可以继续 ...
- 杨氏矩阵定义及其查找的实现C++
先介绍一下这个数据结构的定义,Young Tableau有一个m*n的矩阵,然后有一数组 a[k], 其中 k<=m*n ,然后把a[k]中的数填入 m*n 的矩阵中,填充规则为: 1. 每一 ...