private Observable<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { String[] protocols = beforeHandshake(url, headers, handler); return createRequest(url, headers, protocols) .flatMap(response -> { Observable<WebSocketConnection> conn = response.getWebSocketConnection(); return Observable.zip(Observable.just(response), conn, Tuples::of); }) .flatMap(tuple -> { WebSocketResponse<ByteBuf> response = tuple.getT1(); WebSocketConnection conn = tuple.getT2(); HandshakeInfo info = afterHandshake(url, toHttpHeaders(response)); ByteBufAllocator allocator = response.unsafeNettyChannel().alloc(); NettyDataBufferFactory factory = new NettyDataBufferFactory(allocator); RxNettyWebSocketSession session = new RxNettyWebSocketSession(conn, info, factory); session.aggregateFrames(response.unsafeNettyChannel(), WsClientDecoder.getName()); return RxReactiveStreams.toObservable(handler.handle(session)); }); }