Netty-сервер не принимает пакеты от Netty-клиента

130
02 апреля 2021, 14:20

Такая проблема - имеется сервер, работающий с Netty (используется порт 7755), и принимающий данные в формате JSON (используется Netty >= 4.1 и JsonObjectDecoder), и имеется клиент Netty, отправляющий эти данные.

Для проверки работы сервера, с клиента отправляется тестовый пакет данных в валидном JSON-формате. Однако, сервер не выводит отправленные данныев в STDOUT; отладка также показывает, что сервер не обрабатывает данные, поскольку ChannelInboundHandlerAdapter#channelRead не вызывается.

Но, при попытке отправить эти же тестовые данные через утилиту netcat сервер выводит полученные данные в стандартный вывод:

$ echo '{"key": "value"}' | nc localhost 7755

Клиент:

public class SampleClient {
    public static void main(String[] args) {
        String host = "localhost";
        int port = 7755;
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch)
                        throws Exception {
                    ch.pipeline().addLast(new JsonObjectDecoder(), new ClientChannel());
                }
            });
            ChannelFuture f = b.connect(host, port).sync();
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
}

Сервер:

public class SampleServer {
    private final int port;
    public static void main(String[] args) {
        SampleServer sampleServer = new SampleServer(7755);
        sampleServer.start();
    }
    public SampleServer(int port) {
        this.port = port;
    }
    public void start() {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.localAddress(new InetSocketAddress(port));
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addLast(new JsonObjectDecoder(), new ServerChannel());
                }
            });
            ChannelFuture channelFuture = serverBootstrap.bind().sync();
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

ServerChannel.java:

public class ServerChannel extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("Got a request");
        for (int i = 0; i < byteBuf.capacity(); i++) {
            System.out.print((char) byteBuf.getByte(i));
        }
    }
}

ClientChannel.java:

public class ClientChannel extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Sending request!");
        JsonObject object = new JsonObject();
        object.add("key", new JsonPrimitive("value"));
        ChannelFuture future = ctx.writeAndFlush(object);
        future.addListener(ChannelFutureListener.CLOSE);
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("Channel closed.");
        ctx.close();
    }
}
Answer 1

Итак, немного углубившись в примеры реализаций Netty-клиента, я понял, где была моя ошибка.

Нужно было JSON-объект превращать в строку и записывать его как ByteBuf, чего я не сделал, ошибочно полагая, что Netty все сделает за меня:

ChannelFuture future = ctx.writeAndFlush(Unpooled.copiedBuffer(object.toString(), CharsetUtil.UTF_8));
READ ALSO
Изометрия не получается

Изометрия не получается

Понимаю, что таких тем уже множество, но не одна из них не дала четкое понятие и примера, я пытался сделать его сам из кусков в описаниях этих...

103
Передача параметра через ссылку в подключаемый JS

Передача параметра через ссылку в подключаемый JS

Есть скрипт, который подключается к двум страницам, но выполнение должно отличаться в зависимости от страницыВозможно ли при подключение,...

137
Как доработать регулярное выражение?

Как доработать регулярное выражение?

нуждаюсь в небольшой помощи с регуляркамиУ меня есть регулярное выражение, которое осталось доделать, а сам не справлюсь

131