private void handleWebSocketResponse(ChannelHandlerContext ctx, Outgoing out) { WebSocketHttpResponse response = (WebSocketHttpResponse) out.message; WebSocketServerHandshaker handshaker = response.handshakerFactory().newHandshaker(lastRequest); if (handshaker == null) { HttpResponse res = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.UPGRADE_REQUIRED); res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); HttpUtil.setContentLength(res, 0); super.unbufferedWrite(ctx, new Outgoing(res, out.promise)); response.subscribe(new CancelledSubscriber<>()); } else { // First, insert new handlers in the chain after us for handling the websocket ChannelPipeline pipeline = ctx.pipeline(); HandlerPublisher<WebSocketFrame> publisher = new HandlerPublisher<>(ctx.executor(), WebSocketFrame.class); HandlerSubscriber<WebSocketFrame> subscriber = new HandlerSubscriber<>(ctx.executor()); pipeline.addAfter(ctx.executor(), ctx.name(), "websocket-subscriber", subscriber); pipeline.addAfter(ctx.executor(), ctx.name(), "websocket-publisher", publisher); // Now remove ourselves from the chain ctx.pipeline().remove(ctx.name()); // Now do the handshake // Wrap the request in an empty request because we don't need the WebSocket handshaker ignoring the body, // we already have handled the body. handshaker.handshake(ctx.channel(), new EmptyHttpRequest(lastRequest)); // And hook up the subscriber/publishers response.subscribe(subscriber); publisher.subscribe(response); } }