Такая проблема - имеется сервер, работающий с 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();
}
}
Итак, немного углубившись в примеры реализаций Netty-клиента, я понял, где была моя ошибка.
Нужно было JSON-объект превращать в строку и записывать его как ByteBuf
, чего я не сделал, ошибочно полагая, что Netty все сделает за меня:
ChannelFuture future = ctx.writeAndFlush(Unpooled.copiedBuffer(object.toString(), CharsetUtil.UTF_8));
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Понимаю, что таких тем уже множество, но не одна из них не дала четкое понятие и примера, я пытался сделать его сам из кусков в описаниях этих...
Есть скрипт, который подключается к двум страницам, но выполнение должно отличаться в зависимости от страницыВозможно ли при подключение,...
нуждаюсь в небольшой помощи с регуляркамиУ меня есть регулярное выражение, которое осталось доделать, а сам не справлюсь