У меня есть простой пул соединений Netty и простая конечная точка HTTP, чтобы использовать этот пул для отправки TCP-сообщений в ServerSocket.Соответствующий код выглядит следующим образом: клиент ( NettyConnectionPoolClientApplication ):
@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");
}
});
}
}
и сервер ( 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 и DummyClientHandler просто распечатывают события, которые происходят, поэтому они не релевантны.Когда сервер и клиент запущены, и я отправляю тестовое сообщение на тестовую конечную точку, я вижу, что сервер печатает «Новый клиент подключен», но сообщение, отправленное клиентом, не печатается.Ни одно из последовательных сообщений, отправленных клиентом, не распечатывается сервером.
Если я попытаюсь telnet , все работает нормально, сервер печатает сообщения.Также он работает нормально с обычным клиентом netty с той же конфигурацией начальной загрузки и без пула соединений ( SimpleNettyClientApplication ).
Может кто-нибудь увидеть, что не так с моим пулом соединений, у меня нет идей
Версия Netty: 4.1.39.Final
Весь код доступен здесь .
ОБНОВЛЕНИЕ
Следуя советам Нормана Маурера.Я добавил
ChannelFuture channelFuture = ch
.writeAndFlush(msg + System.lineSeparator());
channelFuture.addListener(writeFuture -> {
System.out
.println("isSuccess(): " + channelFuture.isSuccess() + " : " + channelFuture.cause());
});
Это распечатывает
isSuccess: false : java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)
Чтобы исправить это, я просто преобразовал String
в ByteBuf
ch.writeAndFlush(Unpooled.wrappedBuffer((msg + System.lineSeparator()).getBytes()));