• mina 字节数组编解码器的写法 I


    mina 服务器与 mina 客户端通讯的话,

    一、传递 String 时编解码工厂使用 mina 自带的 TextLineCodecFactory 即可;

    二、传递 java 对象或 byte[] 时编解码工厂使用 ObjectSerializationCodecFactory 即可。

    byte[] 实际上就相当于一个 java 对象,在 mina Object..CodecEncoder 的源码中可以清楚的看到,

    如果传递的不是一个实现了 Serializable 接口的东西,在 encode 方法调用的时候是会抛出异常的。

    见如下代码:

    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
        if (!(message instanceof Serializable)) {
            throw new NotSerializableException();
        }
    
        IoBuffer buf = IoBuffer.allocate(64);
        buf.setAutoExpand(true);
        buf.putObject(message);
    
        int objectSize = buf.position() - 4;
        if (objectSize > maxObjectSize) {
            throw new IllegalArgumentException("The encoded object is too big: " + objectSize + " (> " + maxObjectSize
                    + ')');
        }
    
        buf.flip();
        out.write(buf);
    }
    三、如果是以下一种特殊的情况呢?

    一般的,使用  ObjectSerializationCodecFactory 完成编码操作以后,java 对象就被序列化为便于传递的 byte[] 了。

    但如果我想要 session.write() 出去的 byte[] 数据不经历序列化直接写给另一端呢?

    (byte[]  序列化以后得到的还是 byte[],但是数据会发生改变,长度也会加长很多)。

    很容易就能想到把该端的 ObjectSerializationCodecFactory 过滤器移除掉不就行了么。。

    同时也将另一端的这个过滤器移除掉。。

    但 “不经过解码器直通” 实际上是行不通的。

    在直通的情况下,一端向另一端直接发送的 byte[] 数据,在另一端虽然能接收到,但不会触发该端 hanlder 的 messageRecv 方法。

    换言之,即使是如此简单的一个需求,也还是要书写一个编解码工厂。

    (完成了这一步之后就爽歪歪了,mina 和 c++ 端的通讯将变得没有障碍——byte[] 和 char[]  )

    下面是一个简陋的 byte[] 编解码工厂

    ByteArrayEncoder.java

    package org.bruce.mina.cpp.codec;
    
    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
    import org.apache.mina.filter.codec.ProtocolEncoderOutput;
    
    /**
     * @author BruceYang
     * 
     * 编写编码器的注意事项:
     * 1、 mina 为 IoSession 写队列里的每个对象调用 ProtocolEncode.encode 方法。
     * 因为业务处理器里写出的都是与编码器对应高层对象,所以可以直接进行类型转换。
     * 2、从 jvm 堆分配 IoBuffer,最好避免使用直接缓存,因为堆缓存一般有更好的性能。
     * 3、开发人员不需要释放缓存, mina 会释放。
     * 4、在 dispose 方法里可以释放编码所需的资源。
     */
    public class ByteArrayEncoder extends ProtocolEncoderAdapter {
    
    	@Override
    	public void encode(IoSession session, Object message,
    			ProtocolEncoderOutput out) throws Exception {
    		// TODO Auto-generated method stub
    		byte[] bytes = (byte[])message;
    		
    		IoBuffer buffer = IoBuffer.allocate(256);
    		buffer.setAutoExpand(true);
    		
    		buffer.put(bytes);
    		buffer.flip();
    		
    		out.write(buffer);
    		out.flush();
    		
    		buffer.free();
    	}
    }
    ByteArrayDecoder.java
    package org.bruce.mina.cpp.codec;
    
    import org.apache.mina.core.buffer.IoBuffer;
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
    import org.apache.mina.filter.codec.ProtocolDecoderOutput;
    
    /**
     * @author BruceYang
     *
     */
    public class ByteArrayDecoder extends ProtocolDecoderAdapter {
    
    	@Override
    	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
    			throws Exception {
    		// TODO Auto-generated method stub
    		
    		int limit = in.limit();
    		byte[] bytes = new byte[limit];
    		
    		in.get(bytes);
    		
    		out.write(bytes);
    	}
    	
    }

    ByteArrayCodecFactory.java

    package org.bruce.mina.cpp.codec;
    
    import org.apache.mina.core.session.IoSession;
    import org.apache.mina.filter.codec.ProtocolCodecFactory;
    import org.apache.mina.filter.codec.ProtocolDecoder;
    import org.apache.mina.filter.codec.ProtocolEncoder;
    
    /**
     * @author BruceYang
     *
     */
    public class ByteArrayCodecFactory implements ProtocolCodecFactory {
    	
        private ByteArrayDecoder decoder;
        private ByteArrayEncoder encoder;
        
        public ByteArrayCodecFactory() {
        	encoder = new ByteArrayEncoder();
            decoder = new ByteArrayDecoder();
        }
    
        @Override
        public ProtocolDecoder getDecoder(IoSession session) throws Exception {
            return decoder;
        }
    
        @Override
        public ProtocolEncoder getEncoder(IoSession session) throws Exception {
            return encoder;
        }
    
    }



  • 相关阅读:
    价值理论的出发点和落脚点都是人--以人为本
    价值理论是人类决策和行为的标尺
    事实判断和价值判断
    什么是价值理论?---人们认识世界和改造世界的过程可分解为四个基本阶段
    大人只看利弊 小孩才分对错
    为人处世、事实判断和价值判断皆不可少--人类认识客观事物的标尺:对错与利弊
    知行之间--价值与真理--行动的标尺
    事实判断与价值判断之间的桥梁就是人的需要
    10分钟梳理MySQL核心知识点
    postman设置环境变量,实现一套接口根据选择的环境去请求不同的url
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212027.html
Copyright © 2020-2023  润新知