Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中。目前正在使用 MINA 的软件包括有:Apache Directory Project、AsyncWeb、AMQP(Advanced Message Queuing Protocol)、RED5 Server(Macromedia Flash Media RTMP)、ObjectRADIUS、Openfire 等等。

以上是从网上找到的mina框架简单介绍。
由于正在开发的项目中要求加入及时通信功能(游戏方面),所以在网上找了好几种框架,像openfire、tigase等都是基于Xmpp协议开发的优秀框架。但这些侧重于消息的推送,不适合游戏上的简单交互。所以后来找到了mina这个框架,顺手搭建起来。接下来就是这几天学习的总结了,文章里面没有涉及到逻辑层的方面,只是简单的实现即时通信功能。资源下载我会放在文章的最后面。

一、相关资源下载

(1)Apache官方网站:http://mina.apache.org/downloads.html

(2) Android用jar包(包括官网的资源,我会一律放在百度网盘下)

二、Mina简单配置

  1. 服务器端一共要用到四个jar包,包括一个日志包。将他们放在lib中,并加载进去
    分别为 mina-core-2.0.7.jar  slf4j-log4j12-1.7.6.jar  slf4j-api-1.7.6.jar  log4j-1.2.14.jar(日志管理包)
  2. 如果要使用日志的jar包,则要在项目的src目录下新建一个log4j.properties,添加内容如下:
    log4j.rootCategory=INFO, stdout , R   
    
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.R.File=D:\\Tomcat 5.5\\logs\\qc.log
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n log4j.logger.com.neusoft=DEBUG
    log4j.logger.com.opensymphony.oscache=ERROR
    log4j.logger.net.sf.navigator=ERROR
    log4j.logger.org.apache.commons=ERROR
    log4j.logger.org.apache.struts=WARN
    log4j.logger.org.displaytag=ERROR
    log4j.logger.org.springframework=DEBUG
    log4j.logger.com.ibatis.db=WARN
    log4j.logger.org.apache.velocity=FATAL log4j.logger.com.canoo.webtest=WARN log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
    log4j.logger.org.hibernate=DEBUG
    log4j.logger.org.logicalcobwebs=WARN log4j.rootCategory=INFO, stdout , R log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.R.File=D:\\Tomcat 5.5\\logs\\qc.log
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n log4j.logger.com.neusoft=DEBUG
    log4j.logger.com.opensymphony.oscache=ERROR
    log4j.logger.net.sf.navigator=ERROR
    log4j.logger.org.apache.commons=ERROR
    log4j.logger.org.apache.struts=WARN
    log4j.logger.org.displaytag=ERROR
    log4j.logger.org.springframework=DEBUG
    log4j.logger.com.ibatis.db=WARN
    log4j.logger.org.apache.velocity=FATAL log4j.logger.com.canoo.webtest=WARN log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
    log4j.logger.org.hibernate=DEBUG
    log4j.logger.org.logicalcobwebs=WARN
  3. Android客户端要加入的jar包:mina-core-2.0.7.jar  slf4j-android-1.6.1-RC1.jar 两个jar包(可能直接使用上面的jar包也会行,我没试过~)

二、Mina服务端

我这边使用的是mina2.0版本,所以可能与mina1.0的版本有所不同。那么首先在服务器端创建开始

  1. 新建一个Demo1Server.class文件,里面包含着程序的入口,端口号,Acceptor连接.

     public class Demo1Server {
    //日志类的实现
    private static Logger logger = Logger.getLogger(Demo1Server.class);
    //端口号,要求客户端与服务器端一致
    private static int PORT = 4444; public static void main(String[] args){
    IoAcceptor acceptor = null;
    try{
    //创建一个非阻塞的server端的Socket
    acceptor = new NioSocketAcceptor();
    //设置过滤器(使用mina提供的文本换行符编解码器)
    acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));
    //自定义的编解码器
    //acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
    //设置读取数据的换从区大小
    acceptor.getSessionConfig().setReadBufferSize(2048);
    //读写通道10秒内无操作进入空闲状态
    acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
    //为接收器设置管理服务
    acceptor.setHandler(new Demo1ServerHandler());
    //绑定端口
    acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务器启动成功... 端口号未:"+PORT); }catch(Exception e){
    logger.error("服务器启动异常...",e);
    e.printStackTrace();
    }
    } }

    一个很简单的程序入口吧,简单的说就是在服务器上设置一个消息接收器,让它监听从端口传过来的消息并进行处理。那么接下来我们看看怎么进行消息处理。

  2. 新建一个消息处理类,或者说是是业务逻辑处理器——Demo1ServerHandler,它继承了IoHandlerAdapter类,它默认覆盖了七个方法,而我们主要使用messageReceived()。
    public class Demo1ServerHandler extends IoHandlerAdapter {
    public static Logger logger = Logger.getLogger(Demo1ServerHandler.class); //从端口接受消息,会响应此方法来对消息进行处理
    @Override
    public void messageReceived(IoSession session, Object message)
    throws Exception {
    String msg = message.toString();
    if("exit".equals(msg)){
    //如果客户端发来exit,则关闭该连接
    session.close(true);
    }
    //向客户端发送消息
    Date date = new Date();
    session.write(date);
    logger.info("服务器接受消息成功...");
    super.messageReceived(session, message);
    } //向客服端发送消息后会调用此方法
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    logger.info("服务器发送消息成功...");
    super.messageSent(session, message);
    } //关闭与客户端的连接时会调用此方法
    @Override
    public void sessionClosed(IoSession session) throws Exception {
    logger.info("服务器与客户端断开连接...");
    super.sessionClosed(session);
    } //服务器与客户端创建连接
    @Override
    public void sessionCreated(IoSession session) throws Exception {
    logger.info("服务器与客户端创建连接...");
    super.sessionCreated(session);
    } //服务器与客户端连接打开
    @Override
    public void sessionOpened(IoSession session) throws Exception {
    logger.info("服务器与客户端连接打开...");
    super.sessionOpened(session);
    } @Override
    public void sessionIdle(IoSession session, IdleStatus status)
    throws Exception {
    logger.info("服务器进入空闲状态...");
    super.sessionIdle(session, status);
    } @Override
    public void exceptionCaught(IoSession session, Throwable cause)
    throws Exception {
    logger.info("服务器发送异常...");
    super.exceptionCaught(session, cause);
    }
    }

    很直白的一段程序,相当于将服务器分成了七个状态,而每个状态都有自己的一套逻辑处理方案。

  3. 至此,一个最简单的Mina服务器框架就搭好了,我们可以使用电脑上的telnet命令来测试一下服务器能否使用
    cmd控制台—>telnet <ip地址> <端口号>  如我的服务器ip地为192.168.1.10  那我就写telnet 192.168.1.10 4444 .此时我们可以看到输出日志为

    此时连接已经创建,我们在输入信息服务器就会对信息进行处理,并给出相应的应答。
    (telnet的用法不知道的可以自行百度)

、Mina客户端(Android端)

  1. 服务器简单搭建完毕,那么开始在Android端是配置服务器吧。同样的不要忘记加载jar包, 由于Android自带了Logout,所以就不使用Mina的日志包了。
    由于接受消息会阻塞Android的进程,所以我把它开在子线程中(同时将其放在Service中,让其在后台运行)

     public class MinaThread extends Thread {
    
         private IoSession session = null;
    
         @Override
    public void run() {
    // TODO Auto-generated method stub
    Log.d("TEST","客户端链接开始...");
    IoConnector connector = new NioSocketConnector();
    //设置链接超时时间
    connector.setConnectTimeoutMillis(30000);
    //添加过滤器
    //connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
    connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));
    connector.setHandler(new MinaClientHandler(minaService)); try{
    ConnectFuture future = connector.connect(new InetSocketAddress(ConstantUtil.WEB_MATCH_PATH,ConstantUtil.WEB_MATCH_PORT));//创建链接
    future.awaitUninterruptibly();// 等待连接创建完成
    session = future.getSession();//获得session
    session.write("start");
    }catch (Exception e){
    Log.d("TEST","客户端链接异常...");
    }
    session.getCloseFuture().awaitUninterruptibly();//等待连接断开
    Log.d("TEST","客户端断开...");
    connector.dispose();
    super.run();
    } }

    不知道你们注意到了没,客户端的代码与服务器端的极其相似,不同的是服务器是创建NioSocketAcceptor对象,而客户端是创建NioSocketConnect对象。当然同样需要添加编码解码过滤器和业务逻辑过滤器。

  2. 业务逻辑过滤器代码:

     public class MinaClientHandler extends IoHandlerAdapter{
    
         @Override
    public void exceptionCaught(IoSession session, Throwable cause)
    throws Exception {
    Log.d("TEST","客户端发生异常");
    super.exceptionCaught(session, cause);
    } @Override
    public void messageReceived(IoSession session, Object message)
    throws Exception {
    String msg = message.toString();
    Log.d("TEST","客户端接收到的信息为:" + msg);
    super.messageReceived(session, message);
    } @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    // TODO Auto-generated method stub
    super.messageSent(session, message);
    }
    }

    方法功能与服务器端一样。测试这里就不做了。可以的话自己写个Demo效果更好

、Mina的更多功能

  1. 拿到所有客户端Session

    Collection<IoSession> sessions = session.getService().getManagedSessions().values();
  2. 自定义编码解码器,可以对消息进行预处理。要继承ProtocolEncoder和ProtocolDecode类。
  3. 数据对象的传递

这些功能不便放在这里讲了,可能我会以后再找机会另开一篇来讲述这些功能~,大家可以浏览结尾处的参考文章来加深对mina的理解。

在我认为,熟悉和快速使用一个新的的框架可以看出一个程序员的水平,同样及时总结和归纳自己学到的新知识也是一个好的程序员该具有的习惯。那么Mina的简单搭建就到这里为止了,希望对大家有所帮助。
 
参考文章:(1)Apache MiNa 实现多人聊天室  http://www.cnblogs.com/hoojo/archive/2012/08/01/2617857.html
            (2)MINA官方教程(中文版)    (百度
资源下载:Mina相关资源
 
 ========================================
作者:cpacm
出处:(http://www.cpacm.net/2015/03/22/Mina框架的学习笔记——Android客户端的实现/

Mina框架的学习笔记——Android客户端的实现的更多相关文章

  1. Android Mina框架的学习笔记

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  2. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

  3. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  4. DBFlow框架的学习笔记之入门

    什么是DBFlow? dbflow是一款android高性的ORM数据库.可以使用在进行项目中有关数据库的操作.github下载源码 1.环境配置 先导入 apt plugin库到你的classpat ...

  5. Android动画学习笔记-Android Animation

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  6. jfinal框架教程-学习笔记

    jfinal框架教程-学习笔记 JFinal  是基于 Java  语言的极速  WEB  + ORM  开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restfu ...

  7. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

  8. golang日志框架--logrus学习笔记

    golang日志框架--logrus学习笔记 golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数,对于更精细的日志级别.日志文件分割以及日志分发等方面并没有提供 ...

  9. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

随机推荐

  1. MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':ge

    数据库表里命名有这个字段,可怎么就是报错呢,大神的解释: 加上之后立马好用!!!

  2. LoadRunner使用代理远程执行提示找不到“pre_cci.c”文件

    好久没有使用LoadRunner了,工作需要使用一下,执行总是提示找不到“pre_cci.c”文件,找问题花了很长时间终于找到问题了.万事还是需要找到原因: cci 会将 pre_cci.c 文件作为 ...

  3. Servlet过滤器---登录权限控制

    实现了登录时权限控制:进入首页.登录页以及登录servlet时,不用验证权限:进入其它页面时,须验证是否登录,未登录则跳转到登录页. 一个简单的首页:index.jsp <%@ page lan ...

  4. android stadio 快捷键最好的材料 android stadio大全 最牛逼的android stadio快捷键

    一: .nn .if .for .toast .instanceof .switch 这些都是可以直接点的,一个变量然后.for ,如果这个这个变量是个集合,都可以.for 二: 关闭所有窗口 ctr ...

  5. CentOS 单用户模式:修改Root密码和grub加密[转]

    原文出处: http://zhengdl126.iteye.com/blog/430268 Linux 系统处于正常状态时,服务器主机开机(或重新启动)后,能够由系统引导器程序自动引导 Linux 系 ...

  6. Category的真相

    Objective-C 中的 Category 就是对设计模式中装饰模式的一种具体实现.它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法. 使用场景 根据苹果官方文档对 Categor ...

  7. 发布“豪情”设计的新博客皮肤-darkgreentrip

    豪情 (http://www.cnblogs.com/jikey/)是一名在上海的前端开发人员,长期驻扎在园子里.他为大家设计了一款新的博客皮肤——darkgreentrip. 以下是该博客皮肤的介绍 ...

  8. MQ消息中间件

    MQ是什么? MQ是Message Queue消息队列的缩写.消息队列是一种应用程序对应用程序的通信方法.应用程序通过写和检索入列队的针对应用程序的数据(消息)来进行通信,而不需要专用连接来链接它们. ...

  9. Java的HttpClient的实现

    HttpClient的概念就是模仿浏览器请求服务端内容,也可以做App和Server之间的链接. 这个是关于Java的HttpClient的简单实例,其实java本身也可以通过自己的net包去做,但是 ...

  10. Vue打包app

    前言 公司之前用的app就是一个套壳挂个链接就能用的app,后来需要添加微信分享方便传播,没办法只好做成混合式的app了, 因为之前做.net用vs可以创建cordova项目也试着玩过,就决定用cor ...