gpt4 book ai didi

java - Netty 4 调用被阻止,简单的 Telnet 服务器

转载 作者:行者123 更新时间:2023-12-01 10:18:59 25 4
gpt4 key购买 nike

我正在尝试使用 Netty Telnet 服务器来玩弄 netty api,以检查是否可以观察到真正的异步行为。

下面是正在使用的三个类

TelnetServer.java

public class TelnetServer {

public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new TelnetServerInitializer());


b.bind(8989).sync().channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

}

TelnetServerInitializer.java

public class TelnetServerInitializer extends ChannelInitializer<SocketChannel> {

private static final StringDecoder DECODER = new StringDecoder();
private static final StringEncoder ENCODER = new StringEncoder();

private static final TelnetServerHandler SERVER_HANDLER = new TelnetServerHandler();


final EventExecutorGroup executorGroup = new DefaultEventExecutorGroup(2);

public TelnetServerInitializer() {

}

@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();


// Add the text line codec combination first,
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
// the encoder and decoder are static as these are sharable
pipeline.addLast(DECODER);
pipeline.addLast(ENCODER);

// and then business logic.
pipeline.addLast(executorGroup,"handler",SERVER_HANDLER);
}
}

TelnetServerHandler.java

/**
* Handles a server-side channel.
*/
@Sharable
public class TelnetServerHandler extends SimpleChannelInboundHandler<String> {

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// Send greeting for a new connection.
ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
ctx.write("It is " + new Date() + " now.\r\n");
ctx.flush();
ctx.channel().config().setAutoRead(true);
}

@Override
public void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
// Generate and write a response.

System.out.println("request = "+ request);

String response;
boolean close = false;
if (request.isEmpty()) {
response = "Please type something.\r\n";
} else if ("bye".equals(request.toLowerCase())) {
response = "Have a good day!\r\n";
close = true;
} else {
response = "Did you say '" + request + "'?\r\n";
}

// We do not need to write a ChannelBuffer here.
// We know the encoder inserted at TelnetPipelineFactory will do the conversion.
ChannelFuture future = ctx.write(response);

Thread.sleep(10000);
// Close the connection after sending 'Have a good day!'
// if the client has sent 'bye'.
if (close) {
future.addListener(ChannelFutureListener.CLOSE);
}
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

现在,当我通过 telnet 客户端连接并发送命令 hello hello hello 三次

在完成对channelRead的第一个响应之前,请求不会到达channelRead,有什么方法可以使其完全异步,以便在套接字上可用时立即接收三个hello。

最佳答案

Netty 对每个处理程序的每次传入读取使用最多 1 个线程,这意味着对 channelRead 的下一次调用只会在上一个调用完成后才会调度。这是大多数处理程序正确工作所必需的,包括以正确的顺序发回消息。如果计算量确实很复杂,另一种解决方案是为消息使用自定义线程池。

如果其他操作是其他类型的连接,您也应该将其用作异步连接。只有每个部分都正确执行此操作,您才能实现异步。

关于java - Netty 4 调用被阻止,简单的 Telnet 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35744076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com