FrameDecoder
public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implements LifeCycleAwareChannelHandler {
public static final int DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS = 1024;
private boolean unfold;
protected ChannelBuffer cumulation;
private volatile ChannelHandlerContext ctx;
private int copyThreshold;
private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPON
@Override
public void messageReceived(
ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object m = e.getMessage();
if (!(m instanceof ChannelBuffer)) {
ctx.sendUpstream(e);
return;
}
ChannelBuffer input = (ChannelBuffer) m;
if (!input.readable()) {
return;
}
if (cumulation == null) {
try {
// the cumulation buffer is not created yet so just pass the input to callDecode(...) method
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
} finally {
updateCumulation(ctx, input);
}
} else {
input = appendToCumulation(input);
try {
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
} finally {
updateCumulation(ctx, input);
}
}
}
private void callDecode(
ChannelHandlerContext context, Channel channel,
ChannelBuffer cumulation, SocketAddress remoteAddress) throws Exception {
while (cumulation.readable()) {
int oldReaderIndex = cumulation.readerIndex();
Object frame = decode(context, channel, cumulation);
if (frame == null) {
if (oldReaderIndex == cumulation.readerIndex()) {
// Seems like more data is required.
// Let us wait for the next notification.
break;
} else {
// Previous data has been discarded.
// Probably it is reading on.
continue;
}
}
if (oldReaderIndex == cumulation.readerIndex()) {
throw new IllegalStateException(
"decode() method must read at least one byte " +
"if it returned a frame (caused by: " + getClass() + ')');
}
//堵塞当前的Work线程的吞吐量
unfoldAndFireMessageReceived(context, remoteAddress, frame);
}
}
protected final void unfoldAndFireMessageReceived(
ChannelHandlerContext context, SocketAddress remoteAddress, Object result) {
if (unfold) {
if (result instanceof Object[]) {
for (Object r: (Object[]) result) {
Channels.fireMessageReceived(context, r, remoteAddress);
}
} else if (result instanceof Iterable<?>) {
for (Object r: (Iterable<?>) result) {
Channels.fireMessageReceived(context, r, remoteAddress);
}
} else {
Channels.fireMessageReceived(context, result, remoteAddress);
}
} else {
Channels.fireMessageReceived(context, result, remoteAddress);
}
}
protected ChannelBuffer updateCumulation(ChannelHandlerContext ctx, ChannelBuffer input) {
ChannelBuffer newCumulation;
int readableBytes = input.readableBytes();
if (readableBytes > 0) {
int inputCapacity = input.capacity();
// If input.readableBytes() == input.capacity() (i.e. input is full),
// there's nothing to save from creating a new cumulation buffer
// even if input.capacity() exceeds the threshold, because the new cumulation
// buffer will have the same capacity and content with input.
if (readableBytes < inputCapacity && inputCapacity > copyThreshold) {
// At least one byte was consumed by callDecode() and input.capacity()
// exceeded the threshold.
cumulation = newCumulation = newCumulationBuffer(ctx, input.readableBytes());
cumulation.writeBytes(input);
} else {
// Nothing was consumed by callDecode() or input.capacity() did not
// exceed the threshold.
if (input.readerIndex() != 0) {
cumulation = newCumulation = input.slice();
} else {
cumulation = newCumulation = input;
}
}
} else {
cumulation = newCumulation = null;
}
return newCumulation;
}
1、为什么FrameDecoder return的对象就是往下传递的对象 ?
Object frame = decode(context, channel, cumulation); -- decode 需要子类实现 byte流反序列化
when frame != null
unfoldAndFireMessageReceived(context, remoteAddress, frame);
Channels.fireMessageReceived(context, result, remoteAddress);
还是调用了sendUpstream
2、buffer里面数据未被读取完怎么办?
updateCumulation(ctx, input); 保存到 cumulation缓存 ( protected ChannelBuffer cumulation;)
3、为什么return null 就可以缓存buffer?
updateCumulation(ctx, input); 保存到 cumulation缓存 ( protected ChannelBuffer cumulation;)
所有源码下载 :https://download.csdn.net/download/netcobol/10308871