【发布时间】:2020-05-29 20:53:27
【问题描述】:
这是一个基于 netty 的 web-socket 应用。但是,当客户端在没有发送CloseWebSocketFrame 的情况下被物理杀死时,服务器需要知道通道已关闭并进行一些清理工作。 IdleStateHandler用于监控通道是否空闲。
这是通道处理程序管道。
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
SSLEngine sslEngine = new SSLServiceBase().getSSLContext().createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
... // business process
pipeline.addLast(new IdleStateHandler(30, 10, 0, TimeUnit.SECONDS));
pipeline.addLast(new HeartbeatHandler());
}
这是HeartbeatHandler的userEventTriggered方法,用于在客户端异常关闭通道时做一些清理工作。
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (IdleState.WRITER_IDLE.equals(event.state())) {
ctx.writeAndFlush(new PingWebSocketFrame()).addListener(future -> {
if (!future.isSuccess()) {
ChannelFuture closeFuture = ctx.channel().close();
if (closeFuture.isSuccess()) {
System.out.println("ping faild, channel close successfully");
} else {
System.out.println("ping failed, channel close failed");
}
} else {
System.out.println("Ping succeed, keep the channel.");
}
});
}
} else {
super.userEventTriggered(ctx, evt);
}
}
实际上,我不断收到'close failed',并且从服务器视图来看,该频道仍处于活动状态。谁能告诉我为什么无法关闭频道或如何关闭?非常感谢。
【问题讨论】:
标签: java websocket netty channel