push研究——Apache Mina探索初步
虽然google为Android开发者提供了GCM实现push,但是因为需要系统安装了google play、google帐号、系统>2.2、google push服务器在国外等多种原因,在中国,Android上想实现push还需要自己努力。
当前最火的开源push是基于xmpp协议的androidpn。androidpn是基于Mina框架的,所以这里从Mina框架开始入手。看mina官网的说明:
Server
下面通过简单的例子来学习mina的使用。首先创建服务端,工程正使用了3个jar包
看代码:
public class HelloMina { private static final int PORT = 9125; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //创建一个非阻塞的server端Socket ,用NIO IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast( "logger", new LoggingFilter() ); acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); // 设定服务器端的消息处理器 acceptor.setHandler( new MinaServerHandler() ); acceptor.getSessionConfig().setReadBufferSize( 2048 ); acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ); // 服务器端绑定的端口 启动服务 acceptor.bind( new InetSocketAddress(PORT) ); } }HelloMina的处理器:
/** * HelloMina的处理逻辑 * @author zhangxy */ class MinaServerHandler extends IoHandlerAdapter { @Override public void exceptionCaught( IoSession session, Throwable cause ) throws Exception{ cause.printStackTrace(); session.close(); } @Override public void messageReceived( IoSession session, Object message ) throws Exception { String str = message.toString(); if( str.trim().equalsIgnoreCase("quit") ) { session.close(); return; } System.err.println("收到客户端发来的消息::"+str); StringBuilder buf = new StringBuilder(str.length()); for (int i = str.length() - 1; i >= 0; i--) { buf.append(str.charAt(i)); } // and write it back. session.write(buf.toString()); } @Override public void sessionIdle( IoSession session, IdleStatus status ) throws Exception{ System.out.println( "IDLE " + session.getIdleCount( status )); } @Override public void messageSent(IoSession session, Object message) throws Exception { // TODO Auto-generated method stub super.messageSent(session, message); } @Override public void sessionClosed(IoSession session) throws Exception { // TODO Auto-generated method stub super.sessionClosed(session); System.out.println( "session closed"); } @Override public void sessionCreated(IoSession session) throws Exception { // TODO Auto-generated method stub super.sessionCreated(session); System.out.println( "session create"); } @Override public void sessionOpened(IoSession session) throws Exception { // TODO Auto-generated method stub super.sessionOpened(session); System.out.println( "session opened"); } }
client
下面是Client代码,Client没有使用NIO,使用的普通socket实现:public class HelloMinaClient { private Socket socket; private DataOutputStream out; private DataInputStream in; public HelloMinaClient() throws IOException { } /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub HelloMinaClient minaClient = new HelloMinaClient(); minaClient.minaClient(); } /** * 发送消息 * @param out */ public void sendMessage(Socket s) { try { out = new DataOutputStream(s.getOutputStream()); out.writeBytes("mina\n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void receiveMessage(Socket s) { try { in = new DataInputStream(s.getInputStream()); System.err.println("收到服务端发来的消息::"+in.readLine()); } catch (Exception e) { e.printStackTrace(); } } public void minaClient() throws Exception { while (true) { try { socket = new Socket("192.168.21.121", 9124); sendMessage(socket); receiveMessage(socket); out.close(); in.close(); Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch(Exception e){ e.printStackTrace(); }finally { try{ if(socket!=null)socket.close(); //断开连接 }catch (IOException e) {e.printStackTrace();} } } } }
SOCKET作为短连接,即收发消息后SOCKET断开一次,线程过5秒又建立连接收发消息。
/**
* @author 张兴业
* 邮箱:xy-zhang#163.com
* android开发进阶群:278401545
* http://blog.csdn.net/xyz_lmn
*/