项目结构图如下:
方式: 服务端通过把要发送的数据(这里发送的是对象)编码为amf3格式, 再通过java.util.zip.Deflater 进行压缩,再把压缩后的数据发往客户端.
客户端通过ByteArray.uncompress() 方法解压, 再通过 ByteArray. readObject()方法读取数据(服务端发送的是对象).
mina的文章网上很多, 此项目不再解释.
复制代码即可运行.
方式: 服务端通过把要发送的数据(这里发送的是对象)编码为amf3格式, 再通过java.util.zip.Deflater 进行压缩,再把压缩后的数据发往客户端.
客户端通过ByteArray.uncompress() 方法解压, 再通过 ByteArray. readObject()方法读取数据(服务端发送的是对象).
mina的文章网上很多, 此项目不再解释.
复制代码即可运行.
说明: 由于使用的nio流在进行数据的传输,所以当服务端同时向客户端发送多次数据时(假如同时发送10次),它并不是发送10次,而是将数据进行整合发送,也就是一般发送少于10次. 如下图:
(服务端发送了若干数据,但最终被整合成2个数据段发往客户端. 会触发flash的两次 ProgressEvent.SOCKET_DATA事件)
这个时候客户端在收到"数据段1"后: 通过ByteArray.readObject() 读取对象数据时, 一次只会读取一个数据, 所以要循环读取.
(服务端发送了若干数据,但最终被整合成2个数据段发往客户端. 会触发flash的两次 ProgressEvent.SOCKET_DATA事件)
这个时候客户端在收到"数据段1"后: 通过ByteArray.readObject() 读取对象数据时, 一次只会读取一个数据, 所以要循环读取.
但 这里有个问题, 如果是在服务端先通过amf3output.writeObject(...)写入ByteArrayOutputStream中, 再对ByteArrayOutputStream进行压缩, 那么在客户端解压后, 会出现数据丢失的情况, 即解压后只保留了"数据1", 后面的丢失.
所以服务端要处理为: 先压缩, 再把压缩后的数据写入ByteArrayOutputStream, 再发送给客户端. 客户端接收到后, 循环取出每个数据, 再解压获取真正的数据.
所以服务端要处理为: 先压缩, 再把压缩后的数据写入ByteArrayOutputStream, 再发送给客户端. 客户端接收到后, 循环取出每个数据, 再解压获取真正的数据.
服务端:
AMF3CodecFactory:
package com.test.filter.amf3;
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;
public class AMF3CodecFactory implements ProtocolCodecFactory {
private ProtocolEncoder encoder;
private ProtocolDecoder decoder;
public AMF3CodecFactory() {
encoder = new AMF3Encoder();
decoder = new AMF3Decoder();
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
}
AMF3Decoder:
package com.test.filter.amf3;
import java.util.zip.InflaterInputStream;
import java.io.DataInputStream;
import java.io.UnsupportedEncodingException;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;
import flex.messaging.io.amf.ASObject;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
/**
* <style type="text/css">body{background:#C7EDCC;}</style>
* 解码
* AMF3Decoder.java
* @author yan
*
*/
public class AMF3Decoder extends CumulativeProtocolDecoder {
private final AttributeKey POLICY = new AttributeKey(this.getClass(), "policy");
private final String security = "<policy-file-request/>";
private final SerializationContext context = new SerializationContext();
private final Amf3Input amf3in;
public AMF3Decoder() {
amf3in = new Amf3Input(context);
}
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
if(this.isSecurityRequest(session,in)){
out.write(security);
in.free();
return true;
}else{
in.position(0);
//获取flash socket传入的信息.此时客户端传入的是一个as对象
amf3in.setInputStream(new InflaterInputStream(new DataInputStream(in.asInputStream())));
Object message = amf3in.readObject();
if(message instanceof ASObject){
out.write(message);
in.free();
return true;
}else{
in.free();
return false;
}
}
}
/**
* <style type="text/css">body{background:#C7EDCC;}</style>
* 是否为策略文件请求
* @param session
* @param in
* @return
*/
private boolean isSecurityRequest(IoSession session, IoBuffer in){