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 ...
随机推荐
- WorkFlowHelper
/* # Microshaoft /r:System.Xaml.dll /r:System.Activities.dll /r:System.Activities.DurableInstancing. ...
- strtok源码 bitset 空间压缩
源代码里有一段: unsigned char map[32]; /* Clear control map */ for (count = 0; count < 32; count++) map[ ...
- android中如何用代码来关闭打开的相机
场景描述: 比如你再应用中打开了系统相机,然后需要在几分钟后自动关闭这个系统相机(不是手动关闭) 1.在activityA中利用startActivityForResult(intent,reques ...
- 安装openssl 扩展的时候出现Cannot find config.m4. Make sure that you run '/usr/local/php/bin/phpize' in the top level source directory of the module的解决方法
进入php源码包目录:cd /usr/local/php-5.6.25/ext/openssl 执行命令: cp ./config0.m4 ./config.m4 即可
- iOS之 状态栏字体颜色的设置
前一段时间接手一个项目后,熟悉的过程中发现了不少问题,其中有一个就是关于状态栏的问题. 我们都知道:状态栏字体颜色在不同界面不一样的,原因是系统设置的时候把状态栏的字体颜色的界面控制器设置的yes. ...
- Java设置session超时(失效)的三种方式
1. 在web容器中设置(此处以tomcat为例) 在tomcat-6.0\conf\web.xml中设置,以下是tomcat 6.0中的默认配置: <!-- ================= ...
- 关于null值的排序
关于空值null的排序问题 Oracle排序中NULL值处理的五种常用方法: 1.缺省Oracle在Order by 时缺省认为null是最大值,所以如果是ASC升序则排在最后,DESC降序则排在 ...
- 再记录一下如何配置oracle instantclient
这问题遇到很多次,每次重装系统就遇到一次,却总是搞半天才搞定. 今天再次花费几个小时解决,终于有一个清晰的认识必须记录一下. 一.下载解压,不建任何目录,直接复制tnsname.ora过来.(当然也可 ...
- web.xml配置错误导致applicationContext.xml配置重复加载
web.xml相关配置 <context-param><param-name>log4jRefreshInterval</param-name><param- ...
- Markdown 语法总结
Markdown 语法总结 Markdown是一个神奇的语言,他比html简单,它巧妙地将内容和格式结合起来.很多平台支持Markdown语法编辑,比如github.博客园等. 下面总结一Markdo ...