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;
    }

}


 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM