package org.leo.server.panama.core.handler.tcp; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; import org.leo.server.panama.core.connector.Request; import org.leo.server.panama.core.connector.impl.TCPRequest; import org.leo.server.panama.core.handler.RequestHandler; import java.util.Arrays; public class TCPRequestHandler extends ChannelInboundHandlerAdapter { private Request request; private byte []data; private RequestHandler requestHandler; public TCPRequestHandler(RequestHandler requestHandler) { this.requestHandler = requestHandler; } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { requestHandler.onConnect(ctx); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { data = null; requestHandler.onClose(ctx); super.channelInactive(ctx); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (null == request) { request = new TCPRequest(ctx); } byte []readData = read(ctx, msg); if (null == data || data.length == 0) { data = readData; } else { int start = data.length; data = Arrays.copyOf(data, start + readData.length); System.arraycopy(readData, 0, data, start, readData.length); } // super.channelRead(ctx, msg); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { if (null == data || null == request) { super.channelReadComplete(ctx); return; } request.setData(data); doRequest(request); request = null; data = null; super.channelReadComplete(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { data = null; ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); requestHandler.onClose(ctx); super.exceptionCaught(ctx, cause); } protected void doRequest(Request request) { this.requestHandler.doRequest(request); } protected byte[] read(ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; try { if (!byteBuf.hasArray()) { byte []dataSequence = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(dataSequence); return dataSequence; } return null; } finally { ReferenceCountUtil.release(byteBuf); } } }