nio/mina(三) mina传对象

参考文章: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默认应该就是长连接所以默认不关闭.

 

 

 

posted @ 2012-08-20 14:30  00000000O  阅读(187)  评论(0编辑  收藏  举报