nio/mina(三) mina传对象

leegh 2016-01-05

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

相关推荐

fengshantao / 0评论 2016-03-25

claytang / 0评论 2013-05-06