Source:
public void testClientHandshakerForceClose() throws Exception { final WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker( new URI("ws://localhost:1234/test"), WebSocketVersion.V13, null, true, EmptyHttpHeaders.INSTANCE, Integer.MAX_VALUE, true, false, 20); EmbeddedChannel serverChannel = createServerChannel( new CloseNoOpServerProtocolHandler("/test"), new SimpleChannelInboundHandler<Object>() { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { } }); EmbeddedChannel clientChannel = createClientChannel(handshaker, new SimpleChannelInboundHandler<Object>() { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt == ClientHandshakeStateEvent.HANDSHAKE_COMPLETE) { ctx.channel().closeFuture().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { clientForceClosed = true; } }); handshaker.close(ctx.channel(), new CloseWebSocketFrame()); } } @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { } }); transferAllDataWithMerge(clientChannel, serverChannel); transferAllDataWithMerge(serverChannel, clientChannel); transferAllDataWithMerge(clientChannel, serverChannel); assertTrue(serverReceivedCloseHandshake); assertFalse(clientForceClosed); int attemptsLeft = 5; while (!clientForceClosed && 0 < attemptsLeft--) { Thread.sleep(10); clientChannel.runPendingTasks(); } assertTrue(attemptsLeft > 0); serverChannel.finishAndReleaseAll(); clientChannel.finishAndReleaseAll(); }

Target:
public void testClientHandshakerForceClose() throws Exception { final WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker( new URI("ws://localhost:1234/test"), WebSocketVersion.V13, null, true, EmptyHttpHeaders.INSTANCE, Integer.MAX_VALUE, true, false, 20); EmbeddedChannel serverChannel = createServerChannel( new CloseNoOpServerProtocolHandler("/test"), new SimpleChannelInboundHandler<Object>() { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { } }); EmbeddedChannel clientChannel = createClientChannel(handshaker, new SimpleChannelInboundHandler<Object>() { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt == ClientHandshakeStateEvent.HANDSHAKE_COMPLETE) { ctx.channel().closeFuture().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { clientForceClosed = true; } }); handshaker.close(ctx.channel(), new CloseWebSocketFrame()); } } @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { } }); transferAllDataWithMerge(clientChannel, serverChannel); transferAllDataWithMerge(serverChannel, clientChannel); transferAllDataWithMerge(clientChannel, serverChannel); assertTrue(serverReceivedCloseHandshake); assertFalse(clientForceClosed); while (!clientForceClosed) { Thread.sleep(10); clientChannel.runPendingTasks(); } assertTrue(handshaker.isForceCloseComplete()); assertFalse(serverChannel.finishAndReleaseAll()); assertFalse(clientChannel.finishAndReleaseAll()); }