java - 网络超时后频道未关闭
问题描述
我想在几秒钟后没有收到任何数据时关闭频道。我尝试了 IdleHandler,但它不起作用。我的主要处理程序是 clientHandler,它扩展了 SimpleChannelInboundHandler。这以字符串形式发送数据并以字符串格式接收数据。有时,我希望我的频道在特定超时后关闭,但目前它正在等待来自服务器的数据。
另一项观察是,当我签入数据包发送者以验证相同的请求时。我从服务器收到空响应,但我的 ClientHandler 没有收到此响应。
以下是代码。
clientBootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch){
ch.pipeline()
.addLast(new IdleStateHandler(5, 5, 10))
.addLast(new MyHandler())
.addLast(new ClientHandler(cardIssueRequest,promise));
}
});
我的处理程序:
public class MyHandler extends ChannelDuplexHandler {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if (e.state() == IdleState.READER_IDLE) {
ctx.close();
} else if (e.state() == IdleState.WRITER_IDLE) {
ctx.close();
}
}
}
}
客户端处理程序:
public class ClientHandler extends SimpleChannelInboundHandler {
RequestModel request;
private final Promise<String> promise;
public ClientHandler(RequestModel request, Promise<String> promise) {
this.request = request;
this.promise = promise;
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) {
String response = ((ByteBuf) o).toString(CharsetUtil.UTF_8);
log.info("Client received: " + response);
promise.trySuccess(response);
}
@Override
public void channelActive(ChannelHandlerContext channelHandlerContext) {
log.info("Client sent: " + request);
channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer((request.toString()), CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable cause) {
cause.printStackTrace();
channelHandlerContext.close();
promise.setFailure(cause);
}
}
解决方案
进行线程转储后,我发现问题是我的程序在 promise 语句中等待。因此,在为承诺设置超时后,我的问题得到了解决。
promise.get(60, TimeUnit.SECONDS)
推荐阅读
- laravel - 如何使用嵌套模型加载 Laravel 并限制嵌套模型?
- openedx - 讲师仪表板中缺少 OpenEdX 的电子邮件选项卡?
- javascript - 用js根据其他单元格填表
- ios - 在 Swift 4 中从 uitextfields 将数据发布到服务器
- docker - 无法使用 traefik 的仪表板绑定到端口 8080
- mysql - mysql 8 远程访问
- security - 这对我的程序中的修改检查有用吗?
- jquery - 将视口可见性与 DrawSVG 相结合
- apache-flink - 为什么“广播状态”可以存储动态规则而广播()运算符不能?
- reactjs - Reactjs URL 在 Safari 浏览器上不起作用,仅在生产模式下的 chrome 浏览器上运行 - Netlify