zoukankan      html  css  js  c++  java
  • Mina框架项目运用

    近期最一个项目对通信要求比較严格,须要建立长连接,且能处理多并发,所以选择了Mina框架。以下就简单记录开发的过程吧:

    mina 开发须要的jar包:



    mina pc端通信:


    服务端:


    package cn.ys.net;


    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolCodecFactory;
    import org.apache.mina.filter.codec.ProtocolDecoder;
    import org.apache.mina.filter.codec.ProtocolEncoder;




    /**
     * <b>function:</b> 字符编码、解码工厂类,编码过滤工厂
     * @author hoojo
     * @createDate 2012-6-26 下午01:08:50
     * @file CharsetCodecFactory.java
     * @package com.hoo.mina.code.factory
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetCodecFactory implements ProtocolCodecFactory {
     
        @Override
        public ProtocolDecoder getDecoder(IoSession session) throws Exception {
            return new CharsetDecoder();
        }
     
        @Override
        public ProtocolEncoder getEncoder(IoSession session) throws Exception {
            return new CharsetEncoder();
        }
    }



    package cn.ys.net;


    import java.nio.charset.Charset;


    import org.apache.log4j.Logger;
    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolDecoder;
    import org.apache.mina.filter.codec.ProtocolDecoderOutput;


    /**
     * <b>function:</b> 字符解码
     * @author hoojo
     * @createDate 2012-6-26 上午11:14:18
     * @file CharsetDecoder.java
     * @package com.hoo.mina.code
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetDecoder implements ProtocolDecoder {
     
        private final static Logger log = Logger.getLogger(CharsetDecoder.class);
        
        private final static Charset charset = Charset.forName("UTF-8");    
        // 可变的IoBuffer数据缓冲区
        private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
        
        @Override
        public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
            log.info("#########decode#########");
            
            // 假设有消息
            while (in.hasRemaining()) {
                // 推断消息是否是结束符。不同平台的结束符也不一样;
                // windows换行符( )就觉得是一个完整消息的结束符了; UNIX 是 。MAC 是
                byte b = in.get();
                if (b == ' ') {
                    buff.flip();
                    byte[] bytes = new byte[buff.limit()];
                    buff.get(bytes);
                    String message = new String(bytes, charset);
                    buff = IoBuffer.allocate(100).setAutoExpand(true);
                    
                    // 假设结束了,就写入转码后的数据
                    out.write(message);
                } else {
                    buff.put(b);
                }
            }
        }
     
        @Override
        public void dispose(IoSession session) throws Exception {
            log.info("#########dispose#########");
            log.info(session.getCurrentWriteMessage());
        }
     
        @Override
        public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
            log.info("#########完毕解码#########");
        }
    }


    package cn.ys.net;


    import java.nio.charset.Charset;


    import org.apache.log4j.Logger;
    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolEncoder;
    import org.apache.mina.filter.codec.ProtocolEncoderOutput;
    import org.apache.mina.filter.codec.textline.LineDelimiter;


    /**
     * <b>function:</b> 字符编码
     * @author hoojo
     * @createDate 2012-6-26 上午11:32:05
     * @file CharsetEncoder.java
     * @package com.hoo.mina.code
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetEncoder implements ProtocolEncoder {
        private final static Logger log = Logger.getLogger(CharsetEncoder.class);
        private final static Charset charset = Charset.forName("UTF-8");
        
        @Override
        public void dispose(IoSession session) throws Exception {
            log.info("#############dispose############");
        }
     
        @Override
        public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
            log.info("#############字符编码############");
            IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
            buff.putString(message.toString(), charset.newEncoder());
            // put 当前系统默认换行符
            buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());
            // 为下一次读取数据做准备
            buff.flip();
            
            out.write(buff);
        }
    }



    package cn.ys.net;


    import java.util.Collection;


    import org.apache.mina.core.service.IoHandlerAdapter;
    import org.apache.mina.core.session.IdleStatus;
    import org.apache.mina.core.session.IoSession;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    public class MinaServerHandler extends IoHandlerAdapter{  
    public static Logger logger = LoggerFactory.getLogger(MinaServerHandler.class);  
     
        /**  
        * 这种方法当一个Session 对象被创建的时候被调用。对于TCP 连接来说,连接被接受的时候  
        * 调用,但要注意此时TCP 连接并未建立。此方法仅代表字面含义,也就是连接的对象  
        * IoSession 被创建完成的时候,回调这种方法。

     
        * 对于UDP 来说。当有数据包收到的时候回调这种方法,由于UDP 是无连接的。  
        */   
        @Override  
        public void sessionCreated(IoSession session) throws Exception {  
        System.out.println(1);
       
    //        logger.info("服务端与client创建连接..."+ session.getId()+"  remoteaddress: "+session.getRemoteAddress()+ "  locanaddress"+session.getLocalAddress());  
        }  
      
        /**  
        * 这种方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP 来  
        * 说。它是在连接被建立之后调用,你能够在这里运行一些认证操作、发送数据等。  
        */   
        @Override  
        public void sessionOpened(IoSession session) throws Exception {  
            logger.info("服务端与client连接打开...");  
        }  
      
        /**  
        * 接收到消息时调用的方法,也就是用于接收消息的方法,普通情况下,message 是一个  
        * IoBuffer 类,假设你使用了协议编解码器,那么能够强制转换为你须要的类型。  
        */   
        @Override  
        public void messageReceived(IoSession session, Object message)  
                throws Exception {  
             String msg = message.toString(); 
             String remoteaddress=session.getRemoteAddress().toString();
             
        logger.info("服务端接收到的数据为:" + msg+"  id:  "+ session.getId()+"  remoteaddress: "+remoteaddress+ "  locanaddress"+session.getLocalAddress());
            
         // 拿到全部的clientSession
            Collection<IoSession> sessions = session.getService().getManagedSessions().values();
            // 向全部client发送数据
            int i=0;
            for (IoSession sess : sessions) {
            i++;
            logger.info(" remoteaddress: "+i+"  "+session.getRemoteAddress());
            if(!(remoteaddress.substring(1,14)).equalsIgnoreCase(sess.getRemoteAddress().toString().substring(1,14))){
            sess.write(msg);
            }
            }
            System.out.println("连接数:  "+i);
            
        }  
      
        /**  
        * 当发送消息成功时调用这种方法,注意这里的措辞,发送成功之后,  
        * 也就是说发送消息是不能用这种方法的。  
        */   
        @Override  
        public void messageSent(IoSession session, Object message) throws Exception { 
        System.out.println(4);
        logger.info("id:  "+ session.getId()+"  remoteaddress: "+session.getRemoteAddress()+ "  locanaddress"+session.getLocalAddress());
            logger.info("服务端发送信息成功...");  
        }  
      
        /**  
        * 对于TCP 来说,连接被关闭时。调用这种方法。

     
        * 对于UDP 来说。IoSession 的close()方法被调用时才会毁掉这种方法。  
        */   
        @Override  
        public void sessionClosed(IoSession session) throws Exception { 
            logger.info("服务端连接已经失效");  
        }  
      
        /**  
        * 这种方法在IoSession 的通道进入空暇状态时调用,对于UDP 协议来说,这种方法始终不会  
        * 被调用。

     
        */   
        @Override  
        public void sessionIdle(IoSession session, IdleStatus status)  
                throws Exception {  
            logger.info("服务端进入空暇状态...");  
        }  
      
        /**  
        * 这种方法在你的程序、Mina 自身出现异常时回调,一般这里是关闭IoSession。  
        */   
        @Override  
        public void exceptionCaught(IoSession session, Throwable cause)  
                throws Exception {  
            logger.error("服务端发送异常...", cause);  
        }  
    }  



    package cn.ys.net;


    import java.net.InetSocketAddress;


    import org.apache.mina.core.service.IoAcceptor;
    import org.apache.mina.core.session.IdleStatus;
    import org.apache.mina.filter.codec.ProtocolCodecFilter;
    import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;




    public class MinaServer {  


    private static Logger logger = LoggerFactory.getLogger(MinaServer.class);  
     
        public MinaServer(int port) {
    // TODO Auto-generated constructor stub
        IoAcceptor acceptor = null;  
            try {  
                  
                // 创建一个非堵塞的server端的Socket  
                acceptor = new NioSocketAcceptor();  
                // 设置过滤器(使用Mina提供的文本换行符编解码器)  
                acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
    //            acceptor.getFilterChain().addLast(  
    //                    "codec",  
    //                    new ProtocolCodecFilter(new TextLineCodecFactory(Charset  
    //                            .forName("UTF-8"),  
    //                            LineDelimiter.WINDOWS.getValue(),  
    //                            LineDelimiter.WINDOWS.getValue())));  
                  
                // 设置读取数据的缓冲区大小  
                acceptor.getSessionConfig().setReadBufferSize(2048);  
                // 读写通道10秒内无操作进入空暇状态  
                acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);  
                // 绑定逻辑处理器  
                acceptor.setHandler(new MinaServerHandler());  
                // 绑定port  
                acceptor.bind(new InetSocketAddress(port));  
                logger.info("服务端启动成功...     端口号为:" + port);  
            } catch (Exception e) {  
                logger.error("服务端启动异常....", e);  
                e.printStackTrace();  
            }  
    }
    }  



    client:


    package cn.ys.test;


    import java.net.InetSocketAddress;


    import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
    import org.apache.mina.core.future.CloseFuture;
    import org.apache.mina.core.future.ConnectFuture;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolCodecFilter;
    import org.apache.mina.transport.socket.SocketConnector;
    import org.apache.mina.transport.socket.nio.NioSocketConnector;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;


    import cn.ys.net.CharsetCodecFactory;


    import com.sun.corba.se.impl.javax.rmi.CORBA.Util;


    public class MinaClient {

    private static Logger logger = LoggerFactory.getLogger(MinaClient.class); 

    private SocketConnector connector;
        private ConnectFuture future;
        private IoSession session;
        
        public boolean connect() {
     
        // 创建一个socket连接
            connector = new NioSocketConnector();
            // 设置链接超时时间
            connector.setConnectTimeoutMillis(2000);

            // 获取过滤器链
            DefaultIoFilterChainBuilder filterChain = connector.getFilterChain();
            // 加入编码过滤器 处理乱码、编码问题
            filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
    // .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),
    // LineDelimiter.WINDOWS.getValue())));
     
            try {
     // 消息核心处理器
           connector.setHandler(new MinaClientHandler());

    // TODO Auto-generated method stub
    future = connector.connect(new InetSocketAddress(
    "192.168.1.100", 6969));// 创建连接
    future.awaitUninterruptibly();// 等待连接创建完毕
    session= future.getSession();// 获得session
    } catch (Exception e) {
    // showToast("client链接异常。请检查网络");
    logger.error("client链接异常...", e);
    return false;
    }
            return true;
        }
     
        public void setAttribute(Object key, Object value) {
            session.setAttribute(key, value);
        }
     
        public void send(String message) {
            session.write(message);// 发送消息
    //        session.getCloseFuture().awaitUninterruptibly();// 等待连接断开
        }
     
        public boolean close() {
            CloseFuture future = session.getCloseFuture();
            future.awaitUninterruptibly();
    //        future.awaitUninterruptibly(1000);
            connector.dispose();
            return true;
        }
     
        public SocketConnector getConnector() {
            return connector;
        }
     
        public IoSession getSession() {
            return session;
        }
    }







    package cn.ys.test;




    import org.apache.commons.logging.Log;
    import org.apache.mina.core.service.IoHandlerAdapter;
    import org.apache.mina.core.session.IdleStatus;
    import org.apache.mina.core.session.IoSession;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;




    public class MinaClientHandler extends IoHandlerAdapter {
    private static Logger logger = LoggerFactory 
             .getLogger(MinaClientHandler.class);  

       public static String ini = "没有数据";  
       
       @Override  
       public void messageReceived(IoSession session, Object message)  
               throws Exception {  
    //       Log.d("tag", "message "+ message);  
           
           //接收server发送过来的数据;
    //        String msg = message.toString();  
    //        JSONObject jsonObject=new JSONObject(message.toString());
    //        String msg=jsonObject.get("state").toString();
    //        System.out.println(jsonObject.get("sum"));
    //        String info = "";  
    //       if ("1".equals(msg)) {  
    //        // session.close(); 
    //     //用户登录成功 关闭连接  
    //           info = "登录成功";  
    //        } else {  
    //           info = "登录失败";  
    //        }  
           ini = message.toString();  
    //        session.setAttribute("state", message);  
    //        session.close();  
           logger.info("client接收到的信息为:" + message.toString());  
       }  
     
     
     
      @Override  
       public void exceptionCaught(IoSession session, Throwable cause)  
              throws Exception {  
     
          logger.error("client发生异常...", cause);  
       }  
     
       @Override  
      public void sessionCreated(IoSession arg0) throws Exception {  
           // TODO Auto-generated method stub  
      }  
     
       @Override  
       public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {  
          // TODO Auto-generated method stub  
      }  
     
       /**  
       * 这种方法在连接被打开时调用。它总是在sessionCreated()方法之后被调用。

    对于TCP 来  
       * 说,它是在连接被建立之后调用。你能够在这里运行一些认证操作、发送数据等。

     
       */    
       @Override  
       public void sessionOpened(IoSession arg0) throws Exception {  
           logger.info("ok", "i am ready!");  
    //        System.out.println(6);  
      }  


       
    }




    package cn.ys.test;


    import java.util.Scanner;


    import cn.ys.net.MinaServer;


    public class TestServer {
    public static void main(String[] args) {
    Scanner scanner=new Scanner(System.in);
    // new MinaServer(6969);
    MinaClient client=new MinaClient();
    if(client.connect()){
    client.send("启动客户端成功!

    ");
    while(scanner.hasNext()){
    client.send(scanner.next());
    }
    }
    }
    }


    这是pc端的通信,以下这是android端运用mina与server通信,server端还是不变:

    android端须要的jar 包:



    下面这是代码:



    package com.ys.carclean.net;


    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolCodecFactory;
    import org.apache.mina.filter.codec.ProtocolDecoder;
    import org.apache.mina.filter.codec.ProtocolEncoder;




    /**
     * <b>function:</b> 字符编码、解码工厂类,编码过滤工厂
     * @author hoojo
     * @createDate 2012-6-26 下午01:08:50
     * @file CharsetCodecFactory.java
     * @package com.hoo.mina.code.factory
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetCodecFactory implements ProtocolCodecFactory {
     
        @Override
        public ProtocolDecoder getDecoder(IoSession session) throws Exception {
            return new CharsetDecoder();
        }
     
        @Override
        public ProtocolEncoder getEncoder(IoSession session) throws Exception {
            return new CharsetEncoder();
        }
    }



    package com.ys.carclean.net;


    import java.nio.charset.Charset;


    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolDecoder;
    import org.apache.mina.filter.codec.ProtocolDecoderOutput;


    /**
     * <b>function:</b> 字符解码
     * @author hoojo
     * @createDate 2012-6-26 上午11:14:18
     * @file CharsetDecoder.java
     * @package com.hoo.mina.code
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetDecoder implements ProtocolDecoder {
     
    //    private final static Logger log = Logger.getLogger(CharsetDecoder.class);
        
        private final static Charset charset = Charset.forName("UTF-8");    
        // 可变的IoBuffer数据缓冲区
        private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
        
        @Override
        public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    //        log.info("#########decode#########");
            
            // 假设有消息
            while (in.hasRemaining()) {
                // 推断消息是否是结束符,不同平台的结束符也不一样;
                // windows换行符( )就觉得是一个完整消息的结束符了。 UNIX 是 ;MAC 是
                byte b = in.get();
                if (b == ' ') {
                    buff.flip();
                    byte[] bytes = new byte[buff.limit()];
                    buff.get(bytes);
                    String message = new String(bytes, charset);
                    buff = IoBuffer.allocate(100).setAutoExpand(true);
                    
                    // 假设结束了,就写入转码后的数据
                    out.write(message);
                } else {
                    buff.put(b);
                }
            }
        }
     
        @Override
        public void dispose(IoSession session) throws Exception {
        }
     
        @Override
        public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
        }
    }



    package com.ys.carclean.net;


    import java.nio.charset.Charset;


    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolEncoder;
    import org.apache.mina.filter.codec.ProtocolEncoderOutput;
    import org.apache.mina.filter.codec.textline.LineDelimiter;


    /**
     * <b>function:</b> 字符编码
     * @author hoojo
     * @createDate 2012-6-26 上午11:32:05
     * @file CharsetEncoder.java
     * @package com.hoo.mina.code
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetEncoder implements ProtocolEncoder {
    //    private final static Logger log = Logger.getLogger(CharsetEncoder.class);
        private final static Charset charset = Charset.forName("UTF-8");
        
        @Override
        public void dispose(IoSession session) throws Exception {
    //        log.info("#############dispose############");
        }
     
        @Override
        public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
    //        log.info("#############字符编码############");
            IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
            buff.putString(message.toString(), charset.newEncoder());
            // put 当前系统默认换行符
            buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());
            // 为下一次读取数据做准备
            buff.flip();
            
            out.write(buff);
        }


    }



    package com.ys.carclean.net;


    import java.nio.charset.Charset;


    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolEncoder;
    import org.apache.mina.filter.codec.ProtocolEncoderOutput;
    import org.apache.mina.filter.codec.textline.LineDelimiter;


    /**
     * <b>function:</b> 字符编码
     * @author hoojo
     * @createDate 2012-6-26 上午11:32:05
     * @file CharsetEncoder.java
     * @package com.hoo.mina.code
     * @project ApacheMiNa
     * @blog http://blog.csdn.net/IBM_hoojo
     * @email hoojo_@126.com
     * @version 1.0
     */
    public class CharsetEncoder implements ProtocolEncoder {
    //    private final static Logger log = Logger.getLogger(CharsetEncoder.class);
        private final static Charset charset = Charset.forName("UTF-8");
        
        @Override
        public void dispose(IoSession session) throws Exception {
    //        log.info("#############dispose############");
        }
     
        @Override
        public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
    //        log.info("#############字符编码############");
            IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
            buff.putString(message.toString(), charset.newEncoder());
            // put 当前系统默认换行符
            buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());
            // 为下一次读取数据做准备
            buff.flip();
            
            out.write(buff);
        }


    }






    package com.ys.carclean.net;


    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;


    import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
    import org.apache.mina.core.future.CloseFuture;
    import org.apache.mina.core.future.ConnectFuture;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolCodecFilter;
    import org.apache.mina.filter.codec.textline.LineDelimiter;
    import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
    import org.apache.mina.transport.socket.SocketConnector;
    import org.apache.mina.transport.socket.nio.NioSocketConnector;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;


    import com.ys.carclean.net.util.Util;


    public class MinaClient {

    private static Logger logger = LoggerFactory.getLogger(MinaClient.class); 

    private SocketConnector connector;
        private ConnectFuture future;
        private IoSession session;
        
        public boolean connect() {
     
        // 创建一个socket连接
            connector = new NioSocketConnector();
            // 设置链接超时时间
            connector.setConnectTimeoutMillis(2000);

            // 获取过滤器链
            DefaultIoFilterChainBuilder filterChain = connector.getFilterChain();
            // 加入编码过滤器 处理乱码、编码问题
            filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
    // .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),
    // LineDelimiter.WINDOWS.getValue())));
     
            try {
     // 消息核心处理器
           connector.setHandler(new MinaClientHandler());

    // TODO Auto-generated method stub
    future = connector.connect(new InetSocketAddress(
    Util.HOST, Util.PORT));// 创建连接
    future.awaitUninterruptibly();// 等待连接创建完毕
    session= future.getSession();// 获得session
    } catch (Exception e) {
    // showToast("client链接异常。请检查网络");
    logger.error("client链接异常...", e);
    return false;
    }
            return true;
        }
     
        public void setAttribute(Object key, Object value) {
            session.setAttribute(key, value);
        }
     
        public void send(String message) {
            session.write(message);// 发送消息
    //        session.getCloseFuture().awaitUninterruptibly();// 等待连接断开
        }
     
        public boolean close() {
            CloseFuture future = session.getCloseFuture();
            future.awaitUninterruptibly();
    //        future.awaitUninterruptibly(1000);
            connector.dispose();
            return true;
        }
     
        public SocketConnector getConnector() {
            return connector;
        }
     
        public IoSession getSession() {
            return session;
        }
    }






    package com.ys.carclean.activity;


    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;


    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;


    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;


    import com.ys.carclean.R;
    import com.ys.carclean.net.MinaClient;
    import com.ys.carclean.net.MinaClientHandler;


    public class MainActivity extends Activity {


    private static String LOGIN_NAME = "";

    private Handler handler = new Handler();

    private  MinaClient client = new MinaClient();


    Boolean isconn=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //启动app就发起网络请求
    new Thread(new Runnable() {

    @Override
    public void run() {
    // TODO Auto-generated method stub
    isconn=client.connect();
    }
    }).start();


    Button btn = (Button) findViewById(R.id.btn_send);
    final EditText et=(EditText) findViewById(R.id.et_name);

    btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    LOGIN_NAME = et.getText().toString();
    new Thread(new Runnable() {
    @Override
    public void run() {
    // TODO Auto-generated method stub
    if(isconn){
    // Log.d("tag", LOGIN_NAME  +"  URLEncoder : "+URLEncoder.encode(LOGIN_NAME));

    // SendVo sv=new SendVo();
    // sv.setDestID("2454500");
    // sv.setMsg("89887987");
    // sv.setOperate("开机");

    JSONObject object=new JSONObject();
    try {
    object.put("destId", "6546");
    object.put("msg", "1小时");
    object.put("operate", "1");
    } catch (JSONException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    client.send(object.toString());
    }
    }
    }).start();

    showToast(MinaClientHandler.ini);

    // name.setText("sysadmin"); 设置初始值
    // final Handler myHandler = new Handler() {
    // int i = 0;
    //
    // @Override
    // public void handleMessage(Message msg) { 
    // // 该线程位于主线程
    // // 假设该消息是本程序所发送的
    // if (msg.what == 0x1233) {
    // // 主线程里面 显示操作
    // i++;
    // showToast("第" + i + "次连接開始....");
    // }
    // }
    // };
    // 定义一个计时器。让该计时器周期性的运行指定任务 TimerTask对象的本质就是启动一条新线程
    // new Timer().schedule(new TimerTask() {
    // @Override
    // public void run() {
    // // 新启动的线程无法訪问该Activity里的组件
    // // 所以须要通过Handler发送消息
    // // TODO Auto-generated method stub
    // Message msg = new Message();
    // msg.what = 0x1233;
    // // 发送消息
    // myHandler.sendMessage(msg);
    // LOGIN_NAME = et.getText().toString();
    // //在子线程里面发送请求
    // socketServer();
    // showToast(MinaClientHandler.ini);
    // }
    // }, 0, 10000);

    }
    });

    // 定义一个计时器,让该计时器周期性的运行指定任务 TimerTask对象的本质就是启动一条新线程
    //每5秒。显示下后台传过来的东西
    new Timer().schedule(new TimerTask() {
    @Override
    public void run() {
    //新启动的线程无法訪问该Activity里的组件
    showToast(MinaClientHandler.ini);
    }
    }, 0, 5000);


    }


    public void showToast(final String text) {
    handler.post(new Runnable() {
    @Override
    public void run() {
    Toast.makeText(getApplicationContext(), text,
    Toast.LENGTH_SHORT).show();
    }
    });
    }


    // public void socketServer() {
    // // 创建一个非堵塞的client程序
    // IoConnector connector = new NioSocketConnector();
    // // 设置链接超时时间
    // connector.setConnectTimeout(5);
    // // 加入编码过滤器
    // connector.getFilterChain().addLast(
    // "codec",
    // new ProtocolCodecFilter(new TextLineCodecFactory(Charset
    // .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),
    // LineDelimiter.WINDOWS.getValue())));
    // // 加入业务逻辑处理器类
    // connector.setHandler(new MinaClientHandler());
    // IoSession session=null;
    // try {
    // // 这里是异步操作 连接后马上返回
    // ConnectFuture future = connector.connect(new InetSocketAddress(
    // HOST, PORT));// 创建连接
    // future.awaitUninterruptibly();// 等待连接创建完毕
    // session= future.getSession();// 获得session
    // JSONObject json = createJSONObject();
    //
    // session.write(json);// 发送消息
    //
    // session.getCloseFuture().awaitUninterruptibly();// 等待连接断开
    // connector.dispose();
    // showToast(MinaClientHandler.ini);
    // } catch (Exception e) {
    // showToast("client链接异常,请检查网络");
    // logger.error("client链接异常...", e);
    // }
    //
    // }


    // public static JSONObject createJSONObject() {
    // JSONObject jsonObject = new JSONObject();
    // try {
    // jsonObject.put("username", LOGIN_NAME);
    //// jsonObject.put("sex", "男");
    //// jsonObject.put("QQ", "413425430");
    //// jsonObject.put("Min.score", new Integer(99));
    // jsonObject.put("nickname", "梦中心境");
    // } catch (JSONException e) {
    // e.printStackTrace();
    // }
    // return jsonObject;
    // }
    }


    到这里简单的mina pc端及app与后台通信都能够了。


    以下这就是mina与spring进行整合了:弄了一个中午才搞懂,在spring配置文件了 配置了监听minaport。所以在就不须要在程序里手动启动了。


    配置文件例如以下:


    <!-- mina配置 -->


    <!-- 业务处理逻辑 -->
    <bean id="handler" class="cn.ys.carclean.net.MinaServerHandler" />


    <!-- 累加数据包解码器:解断丢包、粘包问题 -->
    <bean id="codec" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
    <constructor-arg>
    <bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory"></bean>
    <!-- <bean class="cn.ys.carclean.net.CharsetCodecFactory"> -->
    <!-- <constructor-arg index="0"> -->
    <!-- <bean class="cn.ys.carclean.net.CharsetEncoder"></bean> -->
    <!-- </constructor-arg> -->
    <!-- <constructor-arg index="1"> -->
    <!-- <bean class="cn.ys.carclean.net.CharsetDecoder"> -->
    <!-- </bean> -->
    <!-- </constructor-arg> -->


    <!-- </bean> -->
    </constructor-arg>
    </bean>


    <!-- 多线程处理过滤器,为后面的操作开启多线程,一般放在编解码过滤器之后。開始业务逻辑处理 -->
    <bean id="executors" class="org.apache.mina.filter.executor.ExecutorFilter" />
    <!-- Mina自带日志过滤器 默认级别为debug -->
    <bean id="loggerFilter" class="org.apache.mina.filter.logging.LoggingFilter">
    <property name="messageReceivedLogLevel" ref="info"></property>
    <property name="exceptionCaughtLogLevel" ref="info"></property>
    </bean>
    <!-- 枚举类型 依赖注入 须要先通过此类进行类型转换 -->
    <bean id="info"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <property name="staticField" value="org.apache.mina.filter.logging.LogLevel.INFO" />
    </bean>
    <bean id="filterChainBuilder"
    class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
    <property name="filters">
    <map>
    <entry key="codec" value-ref="codec" />
    <entry key="logger" value-ref="loggerFilter" />
    <entry key="executors" value-ref="executors" />
    </map>
    </property>
    </bean>
    <!-- 监听port -->
    <bean id="defaultLocalAddress" class="java.net.InetSocketAddress">
    <constructor-arg index="0" value="8081"></constructor-arg>
    </bean>
    <!-- session config 通过工厂方法注入 -->
    <bean id="sessionConfig" factory-bean="ioAcceptor" factory-method="getSessionConfig">
    <property name="readerIdleTime" value="10" />
    <property name="minReadBufferSize" value="512" />
    <property name="maxReadBufferSize" value="10240" />
    </bean>
    <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
    init-method="bind" destroy-method="unbind">
    <!-- 默认启用的线程个数是CPU 的核数+1, -->
    <!--<constructor-arg index="0" value="10"></constructor-arg> -->
    <property name="defaultLocalAddress" ref="defaultLocalAddress" />
    <property name="handler" ref="handler" />
    <property name="filterChainBuilder" ref="filterChainBuilder" />
    </bean>



    ok 到这里简单学习完成,能够开心的开发项目了!









  • 相关阅读:
    HTML
    MySQL 表操作
    MySQL 库操作
    MySQL
    python 客户端的安全性验证和服务端对客户端的多端连接
    python 黏包
    python 通信
    SpringData —— HelloWorld
    JPA
    Hibernate ——二级缓存
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5074122.html
Copyright © 2011-2022 走看看