APP长连接的实现

一、说明

客户端和服务器端采用Apache的mina框架实现了APP的长连接

二、JAVA服务端

  1. 创建一个基于TCP/IP的非阻塞的server端的Socket
  2. 编写过滤器(使用mina提供的文本换行符编解码器)
  3. 设置读取数据的缓冲区大小
  4. 设置读写通道10秒内无操作进入空闲状态
  5. 为接收器设置管理服务
  6. 为Socket绑定端口

2.1长连接服务器端代码

public class Demo1Server {

    //日志类的实现
    private static Logger logger = Logger.getLogger(Demo1Server.class+"");
    //端口号,要求客户端与服务器端一致
    private static int PORT = 9088;

    public static void main(String[] args){
        IoAcceptor acceptor = null;
        try{
           //创建一个非阻塞的server端的Socket
           acceptor = new NioSocketAcceptor();
           //设置过滤器(使用mina提供的文本换行符编解码器)(在bind前进行)
           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.info("服务器启动异常..."+e.getMessage().toString());
           e.printStackTrace();
       }
   }
}

2.2管理服务代码

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();
        System.out.println(msg);
        if ("exit".equals(msg)) {
            // 如果客户端发来exit,则关闭该连接
            session.close(true);
        }

        // 向客户端发送消息
        Date date = new Date();
        session.write(date);
        logger.info("服务器接受消息成功..." + msg);
        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);
    }

}

三、Android客户端

  1. 创建一个基于TCP/IP的非阻塞的clinet端的Socket
  2. 编写过滤器(使用mina提供的文本换行符编解码器)
  3. 设置连接超时
  4. 为接收器设置管理服务
  5. 连接服务器

3.1长连接客户端代码

注意:
1. Android的网络操作放在子线程
2. 清单文件需要添加访问网络的权限

public class MinaThread extends Thread {
    private IoSession session = null;

    @Override
    public void run() {
        // Create TCP/IP connector.
        IoConnector connector=new NioSocketConnector();
        //编写过滤器,设置编码
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(
                        new TextLineCodecFactory(
                                Charset.forName("UTF-8"),
                                WINDOWS.getValue(),
                                WINDOWS.getValue()
                        )
                )
        );
        //设置超时
        connector.setConnectTimeoutMillis(30000);
        //为连接器设置管理服务
        connector.setHandler(new MinaClientHandler());

        //连接服务器
        connector.connect(new InetSocketAddress(ConstantUtil.IP_ADDRESS, ConstantUtil.PORT));

    }

}

3.2管理服务代码

public class MinaClientHandler extends IoHandlerAdapter {

    //接收到来自服务端的消息
    @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 sessionOpened(IoSession session) throws Exception {
        //向服务器端发送消息
        session.write("this is client");
        super.sessionOpened(session);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        super.messageSent(session, message);
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        Log.d("TEST", "客户端发生异常");
        super.exceptionCaught(session, cause);
    }
}

4.工程链接

APP长连接工程地址_GitHub

你可能感兴趣的:(Android,server,apache,框架,socket)