一、概述
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。
二、服务器端代码
MinaService.java
- package com.czhappy.mina;
- import java.net.InetSocketAddress;
- import java.util.Date;
- import org.apache.mina.core.service.IoAcceptor;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IdleStatus;
- import org.apache.mina.core.session.IoSession;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
- import org.apache.mina.filter.logging.LoggingFilter;
- import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
- public class MinaService {
- public static void main(String[] args) {
- IoAcceptor acceptor = new NioSocketAcceptor();
- //添加日志过滤器
- acceptor.getFilterChain().addLast("logger", new LoggingFilter());
- acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
- acceptor.setHandler(new DemoServerHandler());
- acceptor.getSessionConfig().setReadBufferSize(2048);
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
- try {
- acceptor.bind(new InetSocketAddress(9226));
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("启动服务");
- }
- /**
- * @ClassName: DemoServerHandler
- * @Description: 负责session对象的创建和监听以及消息的创建和接收监听
- * @author chenzheng
- * @date 2016-12-9 下午3:57:11
- */
- private static class DemoServerHandler extends IoHandlerAdapter{
- //服务器与客户端创建连接
- @Override
- public void sessionCreated(IoSession session) throws Exception {
- System.out.println("服务器与客户端创建连接...");
- super.sessionCreated(session);
- }
- @Override
- public void sessionOpened(IoSession session) throws Exception {
- System.out.println("服务器与客户端连接打开...");
- super.sessionOpened(session);
- }
- //消息的接收处理
- @Override
- public void messageReceived(IoSession session, Object message)
- throws Exception {
- // TODO Auto-generated method stub
- super.messageReceived(session, message);
- String str = message.toString();
- Date date = new Date();
- session.write(date.toString());
- System.out.println("接收到的数据:"+str);
- }
- @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);
- }
- }
- }
三、Android客户端代码
ConnectionConfig.java
- package com.czhappy.minaclient;
- import android.content.Context;
- /**
- * Description:构建者模式
- * User: chenzheng
- * Date: 2016/12/9 0009
- * Time: 16:37
- */
- public class ConnectionConfig {
- private Context context;
- private String ip;
- private int port;
- private int readBufferSize;
- private long connectionTimeout;
- public Context getContext() {
- return context;
- }
- public String getIp() {
- return ip;
- }
- public int getPort() {
- return port;
- }
- public int getReadBufferSize() {
- return readBufferSize;
- }
- public long getConnectionTimeout() {
- return connectionTimeout;
- }
- public static class Builder{
- private Context context;
- private String ip = "192.168.168.20";
- private int port = 9226;
- private int readBufferSize = 10240;
- private long connectionTimeout = 10000;
- public Builder(Context context){
- this.context = context;
- }
- public Builder setIp(String ip){
- this.ip = ip;
- return this;
- }
- public Builder setPort(int port){
- this.port = port;
- return this;
- }
- public Builder setReadBufferSize(int readBufferSize){
- this.readBufferSize = readBufferSize;
- return this;
- }
- public Builder setConnectionTimeout(long connectionTimeout){
- this.connectionTimeout = connectionTimeout;
- return this;
- }
- private void applyConfig(ConnectionConfig config){
- config.context = this.context;
- config.ip = this.ip;
- config.port = this.port;
- config.readBufferSize = this.readBufferSize;
- config.connectionTimeout = this.connectionTimeout;
- }
- public ConnectionConfig builder(){
- ConnectionConfig config = new ConnectionConfig();
- applyConfig(config);
- return config;
- }
- }
- }
ConnectionManager.java
- package com.czhappy.minaclient;
- import android.content.Context;
- import android.content.Intent;
- import android.support.v4.content.LocalBroadcastManager;
- import android.util.Log;
- import org.apache.mina.core.future.ConnectFuture;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IoSession;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
- import org.apache.mina.filter.logging.LoggingFilter;
- import org.apache.mina.transport.socket.nio.NioSocketConnector;
- import java.lang.ref.WeakReference;
- import java.net.InetSocketAddress;
- /**
- * Description:
- * User: chenzheng
- * Date: 2016/12/9 0009
- * Time: 16:21
- */
- public class ConnectionManager {
- private static final String BROADCAST_ACTION = "com.commonlibrary.mina.broadcast";
- private static final String MESSAGE = "message";
- private ConnectionConfig mConfig;
- private WeakReference<Context> mContext;
- private NioSocketConnector mConnection;
- private IoSession mSession;
- private InetSocketAddress mAddress;
- public ConnectionManager(ConnectionConfig config){
- this.mConfig = config;
- this.mContext = new WeakReference<Context>(config.getContext());
- init();
- }
- private void init() {
- mAddress = new InetSocketAddress(mConfig.getIp(), mConfig.getPort());
- mConnection = new NioSocketConnector();
- mConnection.getSessionConfig().setReadBufferSize(mConfig.getReadBufferSize());
- mConnection.getFilterChain().addLast("logging", new LoggingFilter());
- mConnection.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
- mConnection.setHandler(new DefaultHandler(mContext.get()));
- mConnection.setDefaultRemoteAddress(mAddress);
- }
- /**
- * 与服务器连接
- * @return
- */
- public boolean connnect(){
- Log.e("tag", "准备连接");
- try{
- ConnectFuture future = mConnection.connect();
- future.awaitUninterruptibly();
- mSession = future.getSession();
- SessionManager.getInstance().setSeesion(mSession);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("tag", "连接失败");
- return false;
- }
- return mSession == null ? false : true;
- }
- /**
- * 断开连接
- */
- public void disContect(){
- mConnection.dispose();
- mConnection=null;
- mSession=null;
- mAddress=null;
- mContext = null;
- Log.e("tag", "断开连接");
- }
- private static class DefaultHandler extends IoHandlerAdapter{
- private Context mContext;
- private DefaultHandler(Context context){
- this.mContext = context;
- }
- @Override
- public void sessionOpened(IoSession session) throws Exception {
- super.sessionOpened(session);
- }
- @Override
- public void messageReceived(IoSession session, Object message) throws Exception {
- Log.e("tag", "接收到服务器端消息:"+message.toString());
- if(mContext!=null){
- Intent intent = new Intent(BROADCAST_ACTION);
- intent.putExtra(MESSAGE, message.toString());
- LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
- }
- }
- }
- }
MinaService.java
- package com.czhappy.minaclient;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.os.HandlerThread;
- import android.os.IBinder;
- import android.support.annotation.Nullable;
- import android.util.Log;
- /**
- * Description:
- * User: chenzheng
- * Date: 2016/12/9 0009
- * Time: 17:17
- */
- public class MinaService extends Service{
- private ConnectionThread thread;
- @Override
- public void onCreate() {
- super.onCreate();
- thread = new ConnectionThread("mina", getApplicationContext());
- thread.start();
- Log.e("tag", "启动线程尝试连接");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- thread.disConnect();
- thread=null;
- }
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- class ConnectionThread extends HandlerThread{
- private Context context;
- boolean isConnection;
- ConnectionManager mManager;
- public ConnectionThread(String name, Context context){
- super(name);
- this.context = context;
- ConnectionConfig config = new ConnectionConfig.Builder(context)
- .setIp("192.168.168.20")
- .setPort(9226)
- .setReadBufferSize(10240)
- .setConnectionTimeout(10000).builder();
- mManager = new ConnectionManager(config);
- }
- @Override
- protected void onLooperPrepared() {
- while(true){
- isConnection = mManager.connnect();
- if(isConnection){
- Log.e("tag", "连接成功");
- break;
- }
- try {
- Log.e("tag", "尝试重新连接");
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public void disConnect(){
- mManager.disContect();
- }
- }
- }
SessionManager.java
- package com.czhappy.minaclient;
- import android.util.Log;
- import org.apache.mina.core.session.IoSession;
- /**
- * Description:
- * User: chenzheng
- * Date: 2016/12/9 0009
- * Time: 17:50
- */
- public class SessionManager {
- private static SessionManager mInstance=null;
- private IoSession mSession;
- public static SessionManager getInstance(){
- if(mInstance==null){
- synchronized (SessionManager.class){
- if(mInstance==null){
- mInstance = new SessionManager();
- }
- }
- }
- return mInstance;
- }
- private SessionManager(){}
- public void setSeesion(IoSession session){
- this.mSession = session;
- }
- public void writeToServer(Object msg){
- if(mSession!=null){
- Log.e("tag", "客户端准备发送消息");
- mSession.write(msg);
- }
- }
- public void closeSession(){
- if(mSession!=null){
- mSession.closeOnFlush();
- }
- }
- public void removeSession(){
- this.mSession=null;
- }
- }
MinaTestActivity.java
- package com.czhappy.minaclient;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.support.v4.content.LocalBroadcastManager;
- import android.support.v7.app.AppCompatActivity;
- import android.util.Log;
- import android.view.View;
- import android.widget.TextView;
- /**
- * Description:
- * User: chenzheng
- * Date: 2016/12/9 0009
- * Time: 18:01
- */
- public class MinaTestActivity extends AppCompatActivity implements View.OnClickListener{
- private TextView start_service_tv, send_tv, receive_tv;
- private MessageBroadcastReceiver receiver;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_mina_test);
- initView();
- registerBroadcast();
- }
- private void registerBroadcast() {
- receiver = new MessageBroadcastReceiver();
- IntentFilter filter = new IntentFilter("com.commonlibrary.mina.broadcast");
- LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
- }
- private void initView() {
- receive_tv = (TextView) this.findViewById(R.id.receive_tv);
- start_service_tv = (TextView) this.findViewById(R.id.start_service_tv);
- start_service_tv.setOnClickListener(this);
- send_tv = (TextView) this.findViewById(R.id.send_tv);
- send_tv.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch(v.getId()){
- case R.id.start_service_tv:
- Log.e("tag", "点击启动服务");
- Intent intent = new Intent(this, MinaService.class);
- startService(intent);
- break;
- case R.id.send_tv:
- Log.e("tag", "点击发送消息");
- SessionManager.getInstance().writeToServer("hello123");
- break;
- }
- }
- private void unregisterBroadcast(){
- LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- stopService(new Intent(this, MinaService.class));
- unregisterBroadcast();
- }
- private class MessageBroadcastReceiver extends BroadcastReceiver{
- @Override
- public void onReceive(Context context, Intent intent) {
- receive_tv.setText(intent.getStringExtra("message"));
- }
- }
- }
四、运行结果
1.点击启动服务,观察客户端是否与服务器端连接成功;
2.点击发送消息,观察消息是否发送成功,如果失败判断失败在哪一步。
客户端运行结果:
服务器端运行结果:
五、源码下载
https://download.csdn.net/download/roshen_android/10378995