zoukankan      html  css  js  c++  java
  • 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默认应该就是长连接所以默认不关闭.

  • 相关阅读:
    工作中遇到的java 内存溢出,问题排查
    java线上内存溢出问题排查步骤
    性能测试-java内存溢出问题排查
    164 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 04 终止finally执行的方法
    163 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 03 使用多重catch结构处理异常
    162 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 02 使用try-catch结构处理异常
    161 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 01 try-catch-finally简介
    160 01 Android 零基础入门 03 Java常用工具类01 Java异常 03 异常处理简介 01 异常处理分类
    159 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 02 异常分类
    158 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 01 什么是异常?
  • 原文地址:https://www.cnblogs.com/nafio/p/9137766.html
Copyright © 2011-2022 走看看