参考文章:http://blog.chinabyte.com/a/534099.html
传递对象的原因:个人理解:符合面向对象,服务器接收客户端消息,需要解析,处理,应答,如果传的是对象,可以把解析,处理,应答写在对象里,这么做,扩展性更好.
客户端
1 MinaClient.java
package com.nafio.client;
import java.net.InetSocketAddress;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
* @author nafio 2012-08-20
* mina传递对象客户端
*/
public class MinaClient {
//使用单例模式
private static MinaClient minaClient = null;
//创建 TCP/IP connector
NioSocketConnector connector = new NioSocketConnector();
//创建接收数据的过滤器
DefaultIoFilterChainBuilder chain = connector.getFilterChain();
//使用单例
//相关的IoHandlerAdapter继承类都采用了单实例模式
//在整个通信过程中做到对象session等实例的单一防止发生“所托非人”的现象//这个不是很理解?
public static MinaClient getInstances() {
if (null == minaClient) {
minaClient = new MinaClient();
}
return minaClient;
}
private MinaClient() {
//设定这个过滤器将按对象读取数据
chain.addLast("myChin", new ProtocolCodecFilter(
new ObjectSerializationCodecFactory()));
connector.setHandler(ClientHandler.getInstances(connector));//by nafio用于彻底关闭客户端连接
//设定连接超时
connector.setConnectTimeout(30);
//连接服务器
ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",
8888));
}
public static void main(String args[]) {
MinaClient.getInstances();
}
}
2 ClientHandler.java
package com.nafio.client;
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.transport.socket.nio.NioSocketConnector;
import com.nafio.obj.TransferObj;
/**
* @author nafio 2012-08-20
* mina传递对象客户端
*/
public class ClientHandler extends IoHandlerAdapter {
private static ClientHandler minaClientHandler = null;
NioSocketConnector connector;//by nafio用于彻底关闭客户端连接
public static ClientHandler getInstances(NioSocketConnector con) {
if (null == minaClientHandler) {
minaClientHandler = new ClientHandler(con);
}
return minaClientHandler;
}
private ClientHandler(NioSocketConnector con) {
connector=con;
}
public void sessionOpened(IoSession session) throws Exception {
//session.write("来自客户端:与服务端会话打开");
System.out.println("客户端:打开了与服务端的会话");
sendMsg(session);
}
//会话结束后触发
public void sessionClosed(IoSession session) {
System.out.println("客户端:与服务端会话结束");
}
//接到返回信息后触发
public void messageReceived(IoSession session, Object message)throws Exception {
System.out.println("客户端:接收到服务端返回信息");
}
//连接创建时触发
public void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
System.out.println("客户端:与服务端连接创建");
}
//连接空闲是触发
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
super.sessionIdle(session, status);
System.out.println("客户端:连接空闲");
}
//发送信息后触发
public void messageSent(IoSession arg0, Object arg1) throws Exception {
//System.out.println("客户端:已向服务器发送-->"+(String)arg1);
System.out.println("客户端:发送对象完毕");
arg0.close();//这里实际不能彻底关闭mina2.0需要connector.dispose()才能彻底关闭
connector.dispose();//不需要关闭去掉这两句就ok
System.out.println("客户端:强行关闭连接");
}
/**
* 传送信息
* @param session
* @throws Exception
*/
public void sendMsg(IoSession session) throws Exception{
TransferObj transferObj=new TransferObj();
transferObj.setDate("nafio_date");
session.write(transferObj);
}
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
super.exceptionCaught(session, cause);
}
}
3 TransferObj.java
package com.nafio.obj;
public class TransferObj implements java.io.Serializable{
private String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
服务端
1 MinaServer.java
package com.nafio.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer {
private static MinaServer minaServer = null;
//创建一个非阻塞的Server端Socket
private SocketAcceptor acceptor = new NioSocketAcceptor();
//创建接收数据的过滤器
private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
private int bindPort = 8888;
//单例
public static MinaServer getInstances() {
if (null == minaServer) {
minaServer = new MinaServer();
}
return minaServer;
}
private MinaServer() {
//设定这个过滤器将按对象读取数据
chain.addLast("myChin", new ProtocolCodecFilter(
new ObjectSerializationCodecFactory()));
//设定服务器端的消息处理器:一个MinaServerHandler对象,
acceptor.setHandler(ServerHandler.getInstances());
try {
//绑定端口,启动服务器
acceptor.bind(new InetSocketAddress(bindPort));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("服务端:监听端口--->" + bindPort);
}
public static void main(String[] args) throws Exception {
MinaServer.getInstances();
}
}
2 ServerHandler.java
package com.nafio.server;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import com.nafio.obj.TransferObj;
//下面两种写法应该等同,不确定?
//public class ServerHandler extends IoHandlerAdapter {
public class ServerHandler extends IoFilterAdapter implements IoHandler {
private static ServerHandler samplMinaServerHandler = null;
public static ServerHandler getInstances() {
if (null == samplMinaServerHandler) {
samplMinaServerHandler = new ServerHandler();
}
return samplMinaServerHandler;
}
private ServerHandler() {
}
public void sessionOpened(IoSession session) throws Exception {
}
public void sessionClosed(IoSession session) {
}
public void messageReceived(IoSession session, Object message)throws Exception {
if (message instanceof TransferObj) {
TransferObj obj = (TransferObj) message;
System.out.println("服务端:收到客户端数据--->"+obj.getDate());
}
}
public void exceptionCaught(IoSession arg0, Throwable arg1)throws Exception {
}
public void messageSent(IoSession arg0, Object arg1) throws Exception {
}
public void sessionCreated(IoSession arg0) throws Exception {
}
public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
}
}
3 TransferObj.java(跟客户端相同,因为客户端和服务端要分开,所以这个类两个工程中都放一个)
彻底关闭mina客户端连接的方法
session.close();
java默认不赞成使用这个方法
这个方法使用后客户端实际还没彻底关闭
mina2.0彻底关闭用connector.dispose();
关于socket长短连接
通常的短连接操作步骤是:
连接→数据传输→关闭连接;
而长连接通常就是:
连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接;
这就要求长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态,短连接在没有数据传输时直接关闭就行了
所以mina默认应该就是长连接所以默认不关闭.