Nettyを使ってサーバを構築する際に、Channel(ソケット)をcloseする際に状況によってFINとRSTを使い分けたい場合があります。例えば、正常時はFIN(遅延タイムアウト時はRST)だけど、異常を検知した際は直ちにRSTにするような要件がある場合です。
close時のデフォルト動作の指定
Channel
をcloseした際のFIN/RSTのどちらを使用するかは、ServerBootstrap
を構築する際に指定することができます。
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(0);
ServerBootstrap bootstrap = new ServerBootstrap()
.option(ChannelOption.SO_BACKLOG, 1024)
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.SO_LINGER, 10) // FIN → 遅延タイムアウト(10秒) → RSTでcloseするための指定
.childHandler(new MyChannelInitializer());
// ...
NOTE:
-1を指定するRSTによる解放は無効化されます。
close時にFIN/RSTを選択
ServerBootstrap
構築時に指定したデフォルト動作と異なる方法でcloseしたい場合は、Channel
からChannelConfig
を取得してSO_LINGERの設定値を変更することで実現することができます。
@ChannelHandler.Sharable
class MyHandler extends SimpleChannelInboundHandler<byte[]> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, byte[] msg) {
// ...
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.channel().config().setOption(ChannelOption.SO_LINGER, 0); // 直ちにRSTでcloseするように指定
ctx.close();
}
}