0
votes

I have a simple netty connection pool and a simple HTTP endpoint to use that pool to send TCP messages to ServerSocket. The relevant code looks like this, the client (NettyConnectionPoolClientApplication) is:

@SpringBootApplication
@RestController
public class NettyConnectionPoolClientApplication {

  private SimpleChannelPool simpleChannelPool;

  public static void main(String[] args) {
    SpringApplication.run(NettyConnectionPoolClientApplication.class, args);
  }

  @PostConstruct
  public void setup() throws Exception {
    EventLoopGroup group = new NioEventLoopGroup();
    Bootstrap bootstrap = new Bootstrap();

    bootstrap.group(group);
    bootstrap.channel(NioSocketChannel.class);
    bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
    bootstrap.remoteAddress(new InetSocketAddress("localhost", 9000));
    bootstrap.handler(new ChannelInitializer<SocketChannel>() {
      protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new DummyClientHandler());
      }
    });
    simpleChannelPool = new SimpleChannelPool(bootstrap, new DummyChannelPoolHandler());
  }

  @RequestMapping("/test/{msg}")
  public void test(@PathVariable String msg) throws Exception {
    Future<Channel> future = simpleChannelPool.acquire();

    future.addListener((FutureListener<Channel>) f -> {
      if (f.isSuccess()) {
        System.out.println("Connected");
        Channel ch = f.getNow();
        ch.writeAndFlush(msg + System.lineSeparator());

        // Release back to pool
        simpleChannelPool.release(ch);
      } else {
        System.out.println("not successful");
      }
    });
  }
}

and the Server (ServerSocketRunner)

public class ServerSocketRunner {

  public static void main(String[] args) throws Exception {
    ServerSocket serverSocket = new ServerSocket(9000);
    while (true) {
      Socket socket = serverSocket.accept();

      new Thread(() -> {
        System.out.println("New client connected");
        try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));) {

          String inputLine, outputLine;
          out.println("Hello client!");

          do {
            inputLine = in.readLine();
            System.out.println("Received: " + inputLine);
          } while (!"bye".equals(inputLine));

          System.out.println("Closing connection...");
          socket.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }).start();
    }
  }
}

DummyChannelPoolHandler and DummyClientHandler just print out events that happen, so they are not relevant. When the server and the client are started and I send a test message to test endpoint, I can see the server prints "New client connected" but the message sent by client is not printed. None of the consecutive messages sent by client are printed by the server.

If I try telnet, everything works fine, the server prints out messages. Also it works fine with regular netty client with same bootstrap config and without connection pool (SimpleNettyClientApplication).

Can anyone see what is wrong with my connection pool, I'm out of ideas

Netty versioin: 4.1.39.Final

All the code is available here.

UPDATE

Following Norman Maurer advice. I added

ChannelFuture channelFuture = ch
    .writeAndFlush(msg + System.lineSeparator());

channelFuture.addListener(writeFuture -> {
  System.out
      .println("isSuccess(): " + channelFuture.isSuccess() + " : " + channelFuture.cause());
});

This prints out

isSuccess: false : java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)

To fix it, I just converted String into ByteBuf

ch.writeAndFlush(Unpooled.wrappedBuffer((msg + System.lineSeparator()).getBytes()));
1

1 Answers

1
votes

You should check what the status of the ChannelFuture is that is returned by writeAndFlush(...). I suspect it is failed.