Android长连接神器框架Mina之服务器和客户端例子

一、概述

        Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。


二、服务器端代码

MinaService.java

[java]  view plain  copy
  1. package com.czhappy.mina;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.util.Date;  
  5.   
  6. import org.apache.mina.core.service.IoAcceptor;  
  7. import org.apache.mina.core.service.IoHandlerAdapter;  
  8. import org.apache.mina.core.session.IdleStatus;  
  9. import org.apache.mina.core.session.IoSession;  
  10. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  11. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;  
  12. import org.apache.mina.filter.logging.LoggingFilter;  
  13. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  14.   
  15. public class MinaService {  
  16.   
  17.     public static void main(String[] args) {  
  18.         IoAcceptor acceptor = new NioSocketAcceptor();  
  19.         //添加日志过滤器  
  20.         acceptor.getFilterChain().addLast("logger"new LoggingFilter());  
  21.         acceptor.getFilterChain().addLast("codec"new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));  
  22.         acceptor.setHandler(new DemoServerHandler());  
  23.         acceptor.getSessionConfig().setReadBufferSize(2048);  
  24.         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);  
  25.         try {  
  26.             acceptor.bind(new InetSocketAddress(9226));  
  27.         } catch (Exception e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         System.out.println("启动服务");  
  31.     }  
  32.       
  33.     /**   
  34.      * @ClassName: DemoServerHandler   
  35.      * @Description: 负责session对象的创建和监听以及消息的创建和接收监听 
  36.      * @author chenzheng 
  37.      * @date 2016-12-9 下午3:57:11   
  38.      */  
  39.     private static class DemoServerHandler extends IoHandlerAdapter{  
  40.           
  41.         //服务器与客户端创建连接  
  42.         @Override  
  43.         public void sessionCreated(IoSession session) throws Exception {  
  44.             System.out.println("服务器与客户端创建连接...");  
  45.             super.sessionCreated(session);  
  46.         }  
  47.   
  48.           
  49.         @Override  
  50.         public void sessionOpened(IoSession session) throws Exception {  
  51.             System.out.println("服务器与客户端连接打开...");  
  52.             super.sessionOpened(session);  
  53.         }  
  54.           
  55.         //消息的接收处理  
  56.         @Override  
  57.         public void messageReceived(IoSession session, Object message)  
  58.                 throws Exception {  
  59.             // TODO Auto-generated method stub  
  60.             super.messageReceived(session, message);  
  61.             String str = message.toString();  
  62.             Date date = new Date();  
  63.             session.write(date.toString());  
  64.             System.out.println("接收到的数据:"+str);  
  65.               
  66.         }  
  67.           
  68.         @Override  
  69.         public void messageSent(IoSession session, Object message)  
  70.                 throws Exception {  
  71.             // TODO Auto-generated method stub  
  72.             super.messageSent(session, message);  
  73.         }  
  74.           
  75.         @Override  
  76.         public void sessionClosed(IoSession session) throws Exception {  
  77.             // TODO Auto-generated method stub  
  78.             super.sessionClosed(session);  
  79.         }  
  80.     }  
  81. }  

三、Android客户端代码

ConnectionConfig.java

[java]  view plain  copy
  1. package com.czhappy.minaclient;  
  2.   
  3. import android.content.Context;  
  4.   
  5. /** 
  6.  * Description:构建者模式 
  7.  * User: chenzheng 
  8.  * Date: 2016/12/9 0009 
  9.  * Time: 16:37 
  10.  */  
  11. public class ConnectionConfig {  
  12.   
  13.     private Context context;  
  14.     private String ip;  
  15.     private int port;  
  16.     private int readBufferSize;  
  17.     private long connectionTimeout;  
  18.   
  19.     public Context getContext() {  
  20.         return context;  
  21.     }  
  22.   
  23.     public String getIp() {  
  24.         return ip;  
  25.     }  
  26.   
  27.     public int getPort() {  
  28.         return port;  
  29.     }  
  30.   
  31.     public int getReadBufferSize() {  
  32.         return readBufferSize;  
  33.     }  
  34.   
  35.     public long getConnectionTimeout() {  
  36.         return connectionTimeout;  
  37.     }  
  38.   
  39.     public static class Builder{  
  40.         private Context context;  
  41.         private String ip = "192.168.168.20";  
  42.         private int port = 9226;  
  43.         private int readBufferSize = 10240;  
  44.         private long connectionTimeout = 10000;  
  45.   
  46.         public Builder(Context context){  
  47.             this.context = context;  
  48.         }  
  49.   
  50.         public Builder setIp(String ip){  
  51.             this.ip = ip;  
  52.             return this;  
  53.         }  
  54.   
  55.         public Builder setPort(int port){  
  56.             this.port = port;  
  57.             return this;  
  58.         }  
  59.   
  60.         public Builder setReadBufferSize(int readBufferSize){  
  61.             this.readBufferSize = readBufferSize;  
  62.             return this;  
  63.         }  
  64.   
  65.         public Builder setConnectionTimeout(long connectionTimeout){  
  66.             this.connectionTimeout = connectionTimeout;  
  67.             return this;  
  68.         }  
  69.   
  70.         private void applyConfig(ConnectionConfig config){  
  71.   
  72.             config.context = this.context;  
  73.             config.ip = this.ip;  
  74.             config.port = this.port;  
  75.             config.readBufferSize = this.readBufferSize;  
  76.             config.connectionTimeout = this.connectionTimeout;  
  77.         }  
  78.   
  79.         public ConnectionConfig builder(){  
  80.             ConnectionConfig config = new ConnectionConfig();  
  81.             applyConfig(config);  
  82.             return config;  
  83.         }  
  84.     }  
  85. }  

ConnectionManager.java

[java]  view plain  copy
  1. package com.czhappy.minaclient;  
  2.   
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.support.v4.content.LocalBroadcastManager;  
  6. import android.util.Log;  
  7.   
  8. import org.apache.mina.core.future.ConnectFuture;  
  9. import org.apache.mina.core.service.IoHandlerAdapter;  
  10. import org.apache.mina.core.session.IoSession;  
  11. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  12. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;  
  13. import org.apache.mina.filter.logging.LoggingFilter;  
  14. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
  15.   
  16. import java.lang.ref.WeakReference;  
  17. import java.net.InetSocketAddress;  
  18.   
  19. /** 
  20.  * Description: 
  21.  * User: chenzheng 
  22.  * Date: 2016/12/9 0009 
  23.  * Time: 16:21 
  24.  */  
  25. public class ConnectionManager {  
  26.   
  27.     private static final String BROADCAST_ACTION = "com.commonlibrary.mina.broadcast";  
  28.     private static final String MESSAGE = "message";  
  29.     private ConnectionConfig mConfig;  
  30.     private WeakReference<Context> mContext;  
  31.   
  32.     private NioSocketConnector mConnection;  
  33.     private IoSession mSession;  
  34.     private InetSocketAddress mAddress;  
  35.   
  36.     public ConnectionManager(ConnectionConfig config){  
  37.   
  38.         this.mConfig = config;  
  39.         this.mContext = new WeakReference<Context>(config.getContext());  
  40.         init();  
  41.     }  
  42.   
  43.     private void init() {  
  44.         mAddress = new InetSocketAddress(mConfig.getIp(), mConfig.getPort());  
  45.         mConnection = new NioSocketConnector();  
  46.         mConnection.getSessionConfig().setReadBufferSize(mConfig.getReadBufferSize());  
  47.         mConnection.getFilterChain().addLast("logging"new LoggingFilter());  
  48.         mConnection.getFilterChain().addLast("codec"new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));  
  49.         mConnection.setHandler(new DefaultHandler(mContext.get()));  
  50.         mConnection.setDefaultRemoteAddress(mAddress);  
  51.     }  
  52.   
  53.     /** 
  54.      * 与服务器连接 
  55.      * @return 
  56.      */  
  57.     public boolean connnect(){  
  58.         Log.e("tag""准备连接");  
  59.         try{  
  60.             ConnectFuture future = mConnection.connect();  
  61.             future.awaitUninterruptibly();  
  62.             mSession = future.getSession();  
  63.   
  64.             SessionManager.getInstance().setSeesion(mSession);  
  65.   
  66.         }catch (Exception e){  
  67.             e.printStackTrace();  
  68.             Log.e("tag""连接失败");  
  69.             return false;  
  70.         }  
  71.   
  72.         return mSession == null ? false : true;  
  73.     }  
  74.   
  75.     /** 
  76.      * 断开连接 
  77.      */  
  78.     public void disContect(){  
  79.         mConnection.dispose();  
  80.         mConnection=null;  
  81.         mSession=null;  
  82.         mAddress=null;  
  83.         mContext = null;  
  84.         Log.e("tag""断开连接");  
  85.     }  
  86.   
  87.     private static class DefaultHandler extends IoHandlerAdapter{  
  88.   
  89.         private Context mContext;  
  90.         private DefaultHandler(Context context){  
  91.             this.mContext = context;  
  92.   
  93.         }  
  94.   
  95.         @Override  
  96.         public void sessionOpened(IoSession session) throws Exception {  
  97.             super.sessionOpened(session);  
  98.         }  
  99.   
  100.         @Override  
  101.         public void messageReceived(IoSession session, Object message) throws Exception {  
  102.             Log.e("tag""接收到服务器端消息:"+message.toString());  
  103.             if(mContext!=null){  
  104.                 Intent intent = new Intent(BROADCAST_ACTION);  
  105.                 intent.putExtra(MESSAGE, message.toString());  
  106.                 LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);  
  107.             }  
  108.         }  
  109.     }  
  110. }  

MinaService.java

[java]  view plain  copy
  1. package com.czhappy.minaclient;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.HandlerThread;  
  7. import android.os.IBinder;  
  8. import android.support.annotation.Nullable;  
  9. import android.util.Log;  
  10.   
  11. /** 
  12.  * Description: 
  13.  * User: chenzheng 
  14.  * Date: 2016/12/9 0009 
  15.  * Time: 17:17 
  16.  */  
  17. public class MinaService extends Service{  
  18.   
  19.     private ConnectionThread thread;  
  20.   
  21.   
  22.     @Override  
  23.     public void onCreate() {  
  24.         super.onCreate();  
  25.         thread = new ConnectionThread("mina", getApplicationContext());  
  26.         thread.start();  
  27.         Log.e("tag""启动线程尝试连接");  
  28.     }  
  29.   
  30.     @Override  
  31.     public int onStartCommand(Intent intent, int flags, int startId) {  
  32.         return super.onStartCommand(intent, flags, startId);  
  33.     }  
  34.   
  35.     @Override  
  36.     public void onDestroy() {  
  37.         super.onDestroy();  
  38.         thread.disConnect();  
  39.         thread=null;  
  40.   
  41.     }  
  42.   
  43.     @Nullable  
  44.     @Override  
  45.     public IBinder onBind(Intent intent) {  
  46.         return null;  
  47.     }  
  48.   
  49.     class ConnectionThread extends HandlerThread{  
  50.   
  51.         private Context context;  
  52.         boolean isConnection;  
  53.         ConnectionManager mManager;  
  54.         public ConnectionThread(String name, Context context){  
  55.             super(name);  
  56.             this.context = context;  
  57.   
  58.             ConnectionConfig config = new ConnectionConfig.Builder(context)  
  59.                     .setIp("192.168.168.20")  
  60.                     .setPort(9226)  
  61.                     .setReadBufferSize(10240)  
  62.                     .setConnectionTimeout(10000).builder();  
  63.   
  64.             mManager = new ConnectionManager(config);  
  65.         }  
  66.   
  67.         @Override  
  68.         protected void onLooperPrepared() {  
  69.             while(true){  
  70.                 isConnection = mManager.connnect();  
  71.                 if(isConnection){  
  72.                     Log.e("tag""连接成功");  
  73.                     break;  
  74.                 }  
  75.                 try {  
  76.                     Log.e("tag""尝试重新连接");  
  77.                     Thread.sleep(3000);  
  78.                 } catch (InterruptedException e) {  
  79.                     e.printStackTrace();  
  80.                 }  
  81.             }  
  82.         }  
  83.   
  84.         public void disConnect(){  
  85.             mManager.disContect();  
  86.         }  
  87.     }  
  88. }  

SessionManager.java

[java]  view plain  copy
  1. package com.czhappy.minaclient;  
  2.   
  3. import android.util.Log;  
  4.   
  5. import org.apache.mina.core.session.IoSession;  
  6.   
  7. /** 
  8.  * Description: 
  9.  * User: chenzheng 
  10.  * Date: 2016/12/9 0009 
  11.  * Time: 17:50 
  12.  */  
  13. public class SessionManager {  
  14.   
  15.     private static SessionManager mInstance=null;  
  16.   
  17.     private IoSession mSession;  
  18.     public static SessionManager getInstance(){  
  19.         if(mInstance==null){  
  20.             synchronized (SessionManager.class){  
  21.                 if(mInstance==null){  
  22.                     mInstance = new SessionManager();  
  23.                 }  
  24.             }  
  25.         }  
  26.         return mInstance;  
  27.     }  
  28.   
  29.     private SessionManager(){}  
  30.   
  31.     public void setSeesion(IoSession session){  
  32.         this.mSession = session;  
  33.     }  
  34.   
  35.     public void writeToServer(Object msg){  
  36.         if(mSession!=null){  
  37.             Log.e("tag""客户端准备发送消息");  
  38.             mSession.write(msg);  
  39.         }  
  40.     }  
  41.   
  42.     public void closeSession(){  
  43.         if(mSession!=null){  
  44.             mSession.closeOnFlush();  
  45.         }  
  46.     }  
  47.   
  48.     public void removeSession(){  
  49.         this.mSession=null;  
  50.     }  
  51. }  

MinaTestActivity.java

[java]  view plain  copy
  1. package com.czhappy.minaclient;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.content.IntentFilter;  
  7. import android.os.Bundle;  
  8. import android.support.v4.content.LocalBroadcastManager;  
  9. import android.support.v7.app.AppCompatActivity;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.widget.TextView;  
  13.   
  14. /** 
  15.  * Description: 
  16.  * User: chenzheng 
  17.  * Date: 2016/12/9 0009 
  18.  * Time: 18:01 
  19.  */  
  20. public class MinaTestActivity extends AppCompatActivity implements View.OnClickListener{  
  21.   
  22.     private TextView start_service_tv, send_tv, receive_tv;  
  23.   
  24.     private MessageBroadcastReceiver receiver;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_mina_test);  
  30.   
  31.         initView();  
  32.         registerBroadcast();  
  33.   
  34.     }  
  35.   
  36.     private void registerBroadcast() {  
  37.         receiver = new MessageBroadcastReceiver();  
  38.         IntentFilter filter = new IntentFilter("com.commonlibrary.mina.broadcast");  
  39.         LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);  
  40.     }  
  41.   
  42.     private void initView() {  
  43.         receive_tv = (TextView) this.findViewById(R.id.receive_tv);  
  44.         start_service_tv = (TextView) this.findViewById(R.id.start_service_tv);  
  45.         start_service_tv.setOnClickListener(this);  
  46.         send_tv = (TextView) this.findViewById(R.id.send_tv);  
  47.         send_tv.setOnClickListener(this);  
  48.   
  49.     }  
  50.   
  51.     @Override  
  52.     public void onClick(View v) {  
  53.         switch(v.getId()){  
  54.             case R.id.start_service_tv:  
  55.                 Log.e("tag""点击启动服务");  
  56.                 Intent intent = new Intent(this, MinaService.class);  
  57.                 startService(intent);  
  58.                 break;  
  59.             case R.id.send_tv:  
  60.                 Log.e("tag""点击发送消息");  
  61.                 SessionManager.getInstance().writeToServer("hello123");  
  62.                 break;  
  63.         }  
  64.     }  
  65.   
  66.     private void unregisterBroadcast(){  
  67.         LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);  
  68.     }  
  69.   
  70.     @Override  
  71.     protected void onDestroy() {  
  72.         super.onDestroy();  
  73.         stopService(new Intent(this, MinaService.class));  
  74.         unregisterBroadcast();  
  75.   
  76.     }  
  77.   
  78.     private class MessageBroadcastReceiver extends BroadcastReceiver{  
  79.         @Override  
  80.         public void onReceive(Context context, Intent intent) {  
  81.   
  82.             receive_tv.setText(intent.getStringExtra("message"));  
  83.         }  
  84.     }  
  85. }  

四、运行结果

1.点击启动服务,观察客户端是否与服务器端连接成功;

2.点击发送消息,观察消息是否发送成功,如果失败判断失败在哪一步。

客户端运行结果:


服务器端运行结果:

五、源码下载

https://download.csdn.net/download/roshen_android/10378995


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值