未能通过承诺,因为它已经完成:

时间:2015-11-11 18:13:05

标签: java netty

我对Netty很陌生,我试图为POST和GET请求创建一个异步http客户端。下面粘贴的代码无论如何工作都很重,我偶尔会遇到以下错误:

    [18:49:56] [nioEventLoopGroup-2-1/WARN]: Failed to fail the promise because it's done already: DefaultChannelPromise@363154df(failure(io.netty.util.IllegalReferenceCountException: refCnt: 0)
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractDerivedByteBuf.release(AbstractDerivedByteBuf.java:50) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf$Component.freeIfNecessary(CompositeByteBuf.java:1335) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.CompositeByteBuf.deallocate(CompositeByteBuf.java:1590) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:106) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:59) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:661) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1054) ~[server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:125) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:192) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:637) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.handler.stream.ChunkedWriteHandler.doFlush(ChunkedWriteHandler.java:258) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:141) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:688) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:669) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.DefaultChannelPipeline.flush(DefaultChannelPipeline.java:838) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.AbstractChannel.flush(AbstractChannel.java:188) [server.jar:git-Spigot-f928e7a-e91aed8]
        at com.werter03886.wtlevelcommand.HttpClient$2.operationComplete(HttpClient.java:120) [WTLevelCommand-1.1.2.jar:?]
        at com.werter03886.wtlevelcommand.HttpClient$2.operationComplete(HttpClient.java:90) [WTLevelCommand-1.1.2.jar:?]
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:680) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:603) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:563) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:406) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:253) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:288) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [server.jar:git-Spigot-f928e7a-e91aed8]
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) [server.jar:git-Spigot-f928e7a-e91aed8]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_31]

这些是我的网络处理程序:

ChannelInitializer

public class HttpInitalizer extends ChannelInitializer<Channel> {

    private final Callback<String> callback;

    public HttpInitalizer(Callback<String> callback) {

        this.callback = callback;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {

        ch.pipeline().addLast("codec", new HttpClientCodec());
        ch.pipeline().addLast("inflater", new HttpContentDecompressor());
        ch.pipeline().addLast("chunkedWriter", new ChunkedWriteHandler());
        ch.pipeline().addLast("handler", new HttpHandler( callback ) );
    }
}

SimpleChannelInboundHandler

@Sharable
public class HttpHandler extends SimpleChannelInboundHandler<HttpObject> {

        private final Callback<String> callback;
        private final StringBuilder buffer = new StringBuilder();

        public HttpHandler (Callback<String> callback) {

                this.callback = callback;
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

                try {

                        callback.done(null, cause);
                }
                catch(Exception ex) {

                        ex.printStackTrace();
                }
                finally {

                        ctx.channel().close();
                }
        }

        protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {

                if (msg instanceof HttpResponse) {

                        HttpResponse response = (HttpResponse) msg;
                        int responseCode = response.getStatus().code();

                        if (responseCode == HttpResponseStatus.NO_CONTENT.code()) {

                                done(ctx);
                                return;
                        }

                        if (responseCode != HttpResponseStatus.OK.code()) {

                                throw new IllegalStateException("Expected HTTP response 200 OK, got " + response.getStatus());
                        }
                }

                if (msg instanceof HttpContent) {

                        HttpContent content = (HttpContent) msg;
                        buffer.append(content.content().toString(CharsetUtil.UTF_8));

                        if (msg instanceof LastHttpContent) {

                                done(ctx);
                        }
                }
        }

        private void done(ChannelHandlerContext ctx) {

                try {

                        callback.done(buffer.toString(), null);
                }
                catch(Exception ex) {

                        ex.printStackTrace();
                }
                finally {

                        ctx.channel().close();
                }
        }
}

HttpClient的

public final class HttpClient {
        public static final int TIMEOUT = 500000;
        private static EventLoopGroup group;

        public HttpClient () {

                group = new NioEventLoopGroup();
        }

        public static void get (String url, final Callback<String> callback) {

                final URI uri = URI.create(url);

                InetAddress inetHost = null;

                try {

                        inetHost = InetAddress.getByName(uri.getHost());
                }
                catch (UnknownHostException e) {

                        e.printStackTrace();
                }

                int port = 80;

                ChannelFutureListener future = new ChannelFutureListener() {

                        public void operationComplete(ChannelFuture future) throws Exception {

                                if (future.isSuccess()) {

                                        String path = uri.getRawPath() + ( ( uri.getRawQuery() == null ) ? "" : "?" + uri.getRawQuery() );
                    HttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, path );
                    request.headers().set(HttpHeaders.Names.HOST, uri.getHost());                  
                    future.channel().writeAndFlush( request );

                                } else {

                                        callback.done(null, future.cause());
                                }
                        }
                };

                new Bootstrap().channel(NioSocketChannel.class).group(group).handler(new HttpInitalizer(callback)).
                option(ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT).remoteAddress(inetHost, port).connect().addListener(future);
        }

        public static void post (String url, final Map<String, Object> params, final Callback<String> callback) {

                final URI uri = URI.create(url);

                InetAddress inetHost = null;

                try {

                        inetHost = InetAddress.getByName(uri.getHost());
                }
                catch (UnknownHostException e) {

                        e.printStackTrace();
                }
                int port = 80;

                ChannelFutureListener future = new ChannelFutureListener() {

                        public void operationComplete(ChannelFuture future) throws Exception {

                                if (future.isSuccess()) {

                                        String path = uri.getRawPath() + ( ( uri.getRawQuery() == null ) ? "" : "?" + uri.getRawQuery() );
                    HttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.POST, path );
                    HttpPostRequestEncoder bodyRequestEncoder = new HttpPostRequestEncoder(request, false);

                    for(Entry<String, Object> es : params.entrySet()) {

                        bodyRequestEncoder.addBodyAttribute(es.getKey(), es.getValue().toString());
                    }

                    request = bodyRequestEncoder.finalizeRequest();
                    request.headers().set(HttpHeaders.Names.HOST, uri.getHost() );    
                    request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
                    request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
                    request.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/x-www-form-urlencoded");

                    future.channel().write(request);

                    if (bodyRequestEncoder.isChunked()) {

                        future.channel().write(bodyRequestEncoder);
                    }

                    future.channel().flush();

                    bodyRequestEncoder.cleanFiles();
                    future.channel().closeFuture();
                                }
                                else {

                                        callback.done(null, future.cause());
                                }
                        }
                };

                new Bootstrap().channel(NioSocketChannel.class).group(group).handler(new HttpInitalizer(callback)).
                option(ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT).remoteAddress(inetHost, port).connect().addListener(future);
        }
}

如果有人能指出我正确的方向,我们将非常感激!

提前谢谢

1 个答案:

答案 0 :(得分:0)

当我将NioSocketChannel用于网络程序时,我遇到了这个问题。我从ChannelHandler接口实现了handlder,没有使用ChannelHandlerAdapter作为扩展的父类。我没有实现的默认方法也没有使用super方法。因此程序运行时有例外,由于IDE的帮助,这是一个愚蠢的错误。