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

  • 相关阅读:
    SQL优化总结之一
    web前端扩展性知识点
    canvas
    开动大脑js小案例(有空就更新的那种)
    本博客在手,jQuery无敌
    小程序整理(持续更新)
    样式初始化代码
    ajax中的async
    跨域问题解决
    ES6学习笔记(持续更新中)
  • 原文地址:https://www.cnblogs.com/nafio/p/9137766.html
Copyright © 2011-2022 走看看