Netty клиент не отправляет данные - PullRequest
1 голос
/ 17 января 2020

Я пытаюсь разработать клиент-сервер для остальных API. Мой клиент находится в Java с Netty, а мой сервер использует golang. В настоящее время у меня возникает действительно странная проблема: мой клиент не отправляет данные запроса POST на сервер при некоторых условиях.

Вот подробности:

- часть моего клиента код:

Bootstrap

      Bootstrap b = new Bootstrap()
              .group(group)
              .channel(NioSocketChannel.class)
              .option(ChannelOption.TCP_NODELAY, true)
              .option(ChannelOption.SO_KEEPALIVE, true)            
              .remoteAddress(Host, Port)
              .handler(new ChannelInitializer<SocketChannel>() {
                  @Override
                  protected void initChannel(SocketChannel ch) {
                      ch.pipeline()
                              .addLast(new HttpClientCodec())
                              .addLast(new ClientHandler());
                  }
              });
      return b.connect().syncUninterruptibly().channel();

Отправить запрос

            if (channel.isActive() && channel.isWritable()) {
                FullHttpRequest postRequest = new DefaultFullHttpRequest(
                        HttpVersion.HTTP_1_1,
                        HttpMethod.POST,
                        uri);
                postRequest.headers().set(HttpHeaderNames.HOST, Host + ":" + Port);
                postRequest.headers().set("Content-Type", "application/json; charset=UTF-8");
                postRequest.headers().set(HttpHeaderNames.CONTENT_LENGTH, data.getBytes(StandardCharsets.UTF_8).length);
                postRequest.content().writeBytes(data.getBytes(StandardCharsets.UTF_8));
                ChannelFuture channelFuture = channel.writeAndFlush(postRequest);
                channelFuture.addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        logger.info("Send completed!");
                    }
                });

- Некоторая информация, полученная от отладки

  • Все работает нормально, когда я запускаю код в IntelliJ, это происходит только при сборке его в файл jar и запуске из файла jar.
  • Когда я перехватываю пакет с помощью wireshark, TCP-квитирование происходит успешно, но данные POST не отправляются.
  • Я думаю, что это как-то связано с длиной данных, если длина данных запроса меньше 150 байт, тогда все в порядке.
  • Netty также сообщает, что отправленная операция завершена (как показано в моем файле журнала "отправка завершена").

Кто-нибудь здесь сталкивался с такими же проблемами ранее или имеет какое-либо представление о как это исправить. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 13 февраля 2020

У меня была проблема, когда netty глотал исключение при использовании асинхронного способа, даже завершая будущее с помощью «Send complete!». Но мои журналы Wireshark никогда не показывали больше, чем поток SYN-> SYN, ACK-> ACK.

Мой код был следующим:

ChannelFuture channelFuture = channel.writeAndFlush(new byte[10]);
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    logger.info("Send completed!");
                }
            });

После того, как я изменил свой код для синхронизации, как Итак:

channel.writeAndFlush(new byte[10]).sync();

Я наконец обнаружил, что на самом деле произошла ошибка:

[11:58:50] [WARN] Исключение было сгенерировано xx.xxxx.xxxxx .ProxyClient.operationComplete () java .lang.UnsupportedOperationException: неподдерживаемый тип сообщения: [B (ожидается: ByteBuf, FileRegion)

Оказывается, мне нужно writeAndFlush(Unpooled.wrappedBuffer(new byte[10])) обернуть мой массив.

Итак, я узнал, что асинхронный способ с радостью скажет вам, что он был успешным!

Но подождите, я потом обнаружил, что он, вероятно, не проглотил никаких исключений, просто я не проверял его !

                @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if(!future.isSuccess()){
                    logger.info(future.cause());
                }
            }

Так что если вы поменяете своего будущего слушателя на проверку isSuccess() и распечатаете причину, это покажет вам ту же ошибку.

Я надеюсь, что если вы осмотрите свое будущее , может быть, вы тоже можете выяснить причину.

...