Это веб-приложение на основе netty. Однако, когда клиент физически убит без отправки 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());
}
Это userEventTriggered
метод HeartbeatHandler
, который используется для Выполните некоторую работу по очистке, когда канал ненормально закрыт от клиента.
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'
, и канал все еще жив с точки зрения сервера. Кто-нибудь может дать мне знать, почему канал не может быть закрыт или как его закрыть? Большое спасибо.