0

I am currently trying to implement compression with netty. I am using the PortUnification example to test this out. But the LengthFieldPrepender is always getting called before the ZlibEncoder.

public class PortUnificationServerHandler extends FrameDecoder
{

    private final boolean detectSsl;
    private final boolean detectGzip;
    private AppConfiguration appConfiguration;
    private final ExecutionHandler executionHandler;

public PortUnificationServerHandler(AppConfiguration pAppConfiguration, ExecutionHandler pExecutionHandler)
{
    appConfiguration = pAppConfiguration;
    this.executionHandler = pExecutionHandler;
    detectGzip = false;
    detectSsl = false;
}

@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception
{

    String lRequest = buffer.toString(CharsetUtil.UTF_8);
    if (ConnectionServiceHelper.isValidJSON(lRequest))
    {
        ObjectMapper lObjectMapper = new ObjectMapper();
        StringReader lStringReader = new StringReader(lRequest);
        JsonNode lNode = lObjectMapper.readTree(lStringReader);
        if (lNode.get(Constants.REQUEST_TYPE).asText().trim().equalsIgnoreCase(Constants.LOGIN_REQUEST))
        {
            JsonNode lDataNode1 = lNode.get(Constants.REQUEST_DATA);
            LoginRequest lLogin = lObjectMapper.treeToValue(lDataNode1, LoginRequest.class);

            if (lLogin.getCompress() != null)
            {
                if (lLogin.getCompress().trim().equalsIgnoreCase(Constants.COMPRESS_FLAG_TRUE))
                {
                    enableJSON(ctx);
                    enableGzip(ctx);
                    ctx.getPipeline().remove(this);
                }
                else
                {
                    enableJSON(ctx);
                    ctx.getPipeline().remove(this);
                }
            }
            else
            {
                enableJSON(ctx);
                ctx.getPipeline().remove(this);

            }
            for (String lName : ctx.getPipeline().getNames())
            {
                System.out.println("Handler Name " + lName);
            }
        }
    }

    // Forward the current read buffer as is to the new handlers.
    return buffer.readBytes(buffer.readableBytes());
}



private void enableJSON(ChannelHandlerContext ctx)
{
    ChannelPipeline pipeline = ctx.getPipeline();

    boolean lHandlerExists = pipeline.getContext("bufferedwriter") != null;

    if (!lHandlerExists)
    {
        pipeline.addFirst("bufferedwriter", new MyBufferedWriteHandler()); // 80960
    }

    lHandlerExists = pipeline.getContext("framer") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); // 80960
    }

    lHandlerExists = pipeline.getContext("decoder") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
    }

    lHandlerExists = pipeline.getContext("encoder") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
    }

    lHandlerExists = pipeline.getContext("executor") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("executor", executionHandler);
    }

    lHandlerExists = pipeline.getContext("handler") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("handler", new ConnectionServiceUpStreamHandler(appConfiguration));
    }

    lHandlerExists = pipeline.getContext("unite") != null;
    if (!lHandlerExists)
    {
        pipeline.addLast("unite", new PortUnificationServerHandler(appConfiguration, executionHandler));
    }
}

private void enableGzip(ChannelHandlerContext ctx)
{
    ChannelPipeline pipeline = ctx.getPipeline();

    boolean lHandlerExists = pipeline.getContext("encoder") != null;
    if (lHandlerExists)
    {
        pipeline.remove("encoder");
    }


    lHandlerExists = pipeline.getContext("gzipdeflater") != null;
    if (!lHandlerExists)
    {
        pipeline.addBefore("executor", "gzipdeflater", new ZlibEncoder(ZlibWrapper.GZIP));
    }


    lHandlerExists = pipeline.getContext("lengthprepender") != null;
    if (!lHandlerExists)
    {
        pipeline.addAfter("gzipdeflater", "lengthprepender", new LengthFieldPrepender(4));
    }


  }
}

Any advice on where i am going wrong ? I am using netty 3.5.11 with jdk 1.7 on Ubuntu 12.4.

Thanks

4

1 に答える 1

0

なぜこれが起こっているのか本当に理解していませんでした。回避策を構築することができました。ZlibEncoderを拡張するカスタムハンドラーを構築し、super.encodeを呼び出した直後に長さの先頭にコードを挿入しました。

素晴らしいフレームワークですが!!

乾杯。

于 2012-12-18T11:13:55.143 に答える