netty在执行clientRequest时抛出“未能将承诺标记为成功”异常

时间:2019-05-20 23:21:32

标签: netty

我有一个已启动并正在运行的Netty代理服务器。 netty收到httpRequest后,将执行以下操作

1)MainHandler#channelRead方法创建一个FullHttpRequest对象,该对象将传递到另一个方法。在这种方法中,我克隆了fullHttpRequest对象,修改了内容(请求主体),使用SubHandler创建了一个客户端bootStrap,并向远程服务器发出了带有修改后的对象的请求。
完成此处理后,我将原始请求对象代理到远程服务器。 我观察到的是,如果我注释掉invokeAndParseClient(这是客户端引导程序),则代理可以正常工作。 如果包含invokeAndParseClient,则会出错(下面的stacktrace)

注意:异常是从proxyRequest抛出的,而不是invokeAndParseClient。

这是启示代码

class MainHandler extends ChannelDuplexHandler {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (msg instanceof HttpRequest) {
        FullHttpRequest request = (FullHttpRequest) msg;
        invokeAndParseClient(request);
        proxyRequest(ctx, request);
        }
}


public void invokeAndParseClient(FullHttpRequest request) {
    FullHttpRequest dup = req.duplicate();
     ByteBuf content = dup.content().copy();
    String newContent = modifiedContent(content); //modifies content to String, do some String replacments
    ByteBuf buf = Unpooled.wrappedBuffer(newContent.getBytes(Charset.forName("UTF-8")));
    dup.replace(buf); //replace content on the request
    BootStrap b = new Bootstrap()
                .group(bossGroup())
                .channel(NioSocketChannel.class)
                .handler(new RemoteChannelInitializer());
                Channel ch = bootstrap.connect(remoteSocketAddress).sync().channel();
                ChannelFuture f = ch.writeAndFlush(clonedReq);
                //need to close channel. but have to figure out when

}

public class RemoteChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast(new LoggingHandler(LogLevel.INFO));
        p.addLast(new HttpClientCodec());
        p.addLast(new HttpObjectAggregator(1024 * 1024, true));
        p.addLast(new ClientHandler()));
    }
}


public class ClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientRequestHandler.class);

    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) {
        LOGGER.info("here you gooooo");

        if (msg instanceof FullHttpResponse) {
            LOGGER.info("this is fullHttpResponse");
            FullHttpResponse full = (FullHttpResponse) msg;
            FullHttpResponse dup = full.copy();
            LOGGER.info("response code ===> " + full.status());
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
    }

使用此代码,我得到以下异常。但是一旦我注释掉invokeAndParseClient(request),它就可以正常工作。 这是什么问题?

2019-05-21 16:08:59.524  WARN 45091 --- [tLoopGroup-3-25] io.netty.channel.ChannelOutboundBuffer   : Failed to mark a promise as success because it has failed already: DefaultChannelPromise@2e4d789f(failure: io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1), unnotified cause:

io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:106) ~[netty-codec-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:348) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:837) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1071) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300) ~[netty-transport-4.1.31.Final.jar:4.1.31.Final]
    at com.example.MainHandler.proxyRequest(ClientRequestHandler.java:178) ~[classes/:na]

0 个答案:

没有答案