1、Mina服务器启动类
import java.net.InetSocketAddress;
import org.apache.log4j.Logger;
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.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
/**
* @author sery
* @date 2018年4月26日 下午2:50:31
* @explain
*/
public class MinaConfig{
private static Logger logger = Logger.getLogger(MinaConfig.class);
private static Integer PORT = 9123;
/** 30秒后超时 */
private static final int IDELTIMEOUT = 30;
/** 15秒发送一次心跳包 */
private static final int HEARTBEATRATE = 15;
/**启动服务类 */
public void start() {
IoAcceptor acceptor = null;// 创建连接
try {
// 创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 设置过滤器(使用Mina提供的文本换行符编解码器)
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
// 设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
// 读写通道30秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,IDELTIMEOUT);
KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,IdleStatus.BOTH_IDLE);
//设置是否forward到下一个filter
heartBeat.setForwardEvent(true);
//设置心跳频率
heartBeat.setRequestInterval(HEARTBEATRATE);
//设置失败处理handler
heartBeat.setRequestTimeoutHandler(new KeepAliveRequestTimeoutHandlerImpl());
acceptor.getFilterChain().addLast("heartbeat", heartBeat);
//绑定逻辑处理器
acceptor.setHandler(new MinaConfigHandler());
// 绑定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服务端启动成功... 端口号为:" + PORT);
}catch (Exception e) {
// TODO: handle exception
logger.error(e);
}
}
}
2、上面的MinaConfigHandler处理类 实现IoHandler就OK了,里面得逻辑略
3、处理心跳类KeepAliveMessageFactoryImpl
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
/**
* @author sery
* @date 2018年8月7日 下午3:13:56
* @explain
*/
public class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {
/** 心跳包内容 */
private static final String HEARTBEATREQUEST = "0x11";
private static final String HEARTBEATRESPONSE = "0x12";
/* (non-Javadoc)
* @see org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isRequest(org.apache.mina.core.session.IoSession, java.lang.Object)
*/
@Override
public boolean isRequest(IoSession ioSession, Object o) {
System.out.println("服务端判断消息是否为请求包消息: "+o);
if (o.equals(HEARTBEATREQUEST))
return true;
return false;
}
@Override
public boolean isResponse(IoSession session, Object message) {
System.out.println("服务端判断消息是否为响应心跳包信息: " + message);
if(message.equals(HEARTBEATRESPONSE))
return true;
return false;
}
@Override
public Object getRequest(IoSession session) {
System.out.println("服务端发送给客户端的心跳包消息: " + HEARTBEATREQUEST);
return HEARTBEATREQUEST;
}
@Override
public Object getResponse(IoSession session, Object request) {
System.out.println("响应预设信息: " + HEARTBEATRESPONSE);
return HEARTBEATRESPONSE;
}
}
4、处理心跳包发送失败的类KeepAliveRequestTimeoutHandlerImpl
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
/**
* @author sery
* @date 2018年8月8日 下午1:12:25
* @explain
*/
public class KeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler{
@Override
public void keepAliveRequestTimedOut(KeepAliveFilter keepAliveFilter, IoSession ioSession) throws Exception {
ioSession.close(true);
System.out.print("客户端挂了 我把session给干掉了!");
}
}
5、提供测试客户端MinaClient
import java.net.InetSocketAddress;
import org.apache.log4j.Logger;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
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.transport.socket.nio.NioSocketConnector;
/**
*
* @author sery
* @date 2018年8月8日 下午5:05:28
* @explain 客户端测试
*/
public class MinaClient {
private static Logger logger = Logger.getLogger(MinaClient.class);
private static int PORT = 9123;
private static String HOST = "192.168.1.72";
public static void main(String[] args){
IoConnector connector = new NioSocketConnector();
connector.setConnectTimeout(30000);
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
connector.setHandler(new ClientHandler());
IoSession session = null;
try {
ConnectFuture future = connector.connect(new InetSocketAddress(HOST, PORT));
future.awaitUninterruptibly();
session= future.getSession();
session.write("Holle Mina@");
}catch (Exception e) {
logger.error("error",e);
}
session.getCloseFuture().awaitUninterruptibly();
connector.dispose();
}
}
6、客户端ClientHandler类,继承IoHandlerAdapter类处理相关逻辑
7、注意两端编解码用相同的方式
8、哈哈,搭建好勒【看小可爱这么勤快,你确定不给个关注~~】