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 [email protected]

* @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 [email protected]

* @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换行符(\r\n)就觉得是一个完整消息的结束符了; UNIX 是\n。MAC 是\r

byte b = in.get();

if (b == ‘\n‘) {

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 [email protected]

* @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 [email protected]

* @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 [email protected]

* @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换行符(\r\n)就觉得是一个完整消息的结束符了。 UNIX 是\n;MAC 是\r

byte b = in.get();

if (b == ‘\n‘) {

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 [email protected]

* @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 [email protected]

* @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 到这里简单学习完成,能够开心的开发项目了!

时间: 2024-10-09 13:10:37

Mina框架项目运用的相关文章

Mina框架研究

Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架. 这个框架的优点: – 异步 – 无阻塞 – 事件驱动 – 支持TCP, UDP, APR, 串口- – 通过 过滤器(Filters)实现扩展性 – 同时提供协议框架 总体框架 之前的一个项目用到了MINA,最近想再系统的整理一下,主要参考MINA 2.0 User

长连接神器Mina框架的使用

前段时间学习了mina框架的使用.它是基于Socket进行通信,所以说在项目中要是需要长连接的使用,那mina框架是一个不错的选择. 下面简单介绍一下mina框架的使用,学习mina框架不长时间,现在写下来即时为了记录一下自己的学习经历,又希望可以帮助其他初学者朋友,若有不足与错误之处,还请大神指教. 在使用mina框架之前需要下载所需的jar包.可以在我的网盘中下载,Android端也可以用的.地址:http://pan.baidu.com/s/1skP8YT3 ,提取码:inyl. 所需的j

Android Mina框架的学习笔记

Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架.当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发.串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中.目前正在使用 MINA 的软件包括有:Apache Directory Project.Asyn

基于MINA框架快速开发网络应用程序

1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用MINA框架可以可以省下处理底层I/O和线程并发等复杂工作,开发人员能够把更多的精力投入到业务设计和开发当中.MINA框架的应用比较广泛,应用的开源项目有Apache Directory.AsyncWeb.Apache Qpid.QuickFIX/J.Openfire.SubEthaSTMP.red5

Mina框架的学习笔记——Android客户端的实现

Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架.当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发.串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中.目前正在使用 MINA 的软件包括有:Apache Directory Project.Asyn

使用Mina框架开发 QQ Android 客户端

Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API. Apache MINA 也称为: ● NIO 框架库 ● 客户端服务器框架库 ● 一个网络套接字库 MINA虽然简单但是仍然提供了全功能的网络应用程序框架: ● 为不同的传输类型提供了统一的API: ○ 通过Java NIO提供TCP/IP 和 UDP/IP支持 ○ 通过RXTX提供串口通讯(

Apache MINA框架整合到Spring框架中

毕业设计用到了Apache公司的MINA框架作为服务端与安卓客户端的通信框架. 问题:服务端分为两个部分,一个是基于javaEE平台的后台管理系统,另一个是基于MINA框架的服务,整个项目中需求是当tomcat服务器启动的时候,将MINA服务也一起启动起来,相当于服务端程序运行起来后,开启两个服务. 分析:服务端的后台管理系统是采用Spring+Hibernate框架整合搭建的,而当tomcat服务器启动后,会加载spring的配置文件,而spring配置文件中可以自定义监听器,将启动MINA服

使用Mina框架实现C/S通讯

什么是Mina? Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily. It provides an abstract event-driven asynchronous API over various transports such as TCP/IP and UDP/

关于mina框架EMFILE: open too many files exception的处理

做项目的时候,用到了mina框架,与server进行交互.由于采用的是短连接+心跳包+断线重连的方式,因此网络不稳定的时候经常会出现断线重连. 那么有时候偶尔会出现EMFILE: open too many files exception的问题,看堆栈信息是出在new socketconnector的时候. Jacklondon Chen的一篇文章 Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法 http://www.cnblogs.co