public final ChannelFuture handshake(Channel channel, final ChannelPromise promise) {
        FullHttpRequest request =  newHandshakeRequest();

        HttpResponseDecoder decoder = channel.pipeline().get(HttpResponseDecoder.class);
        if (decoder == null) {
            HttpClientCodec codec = channel.pipeline().get(HttpClientCodec.class);
            if (codec == null) {
               promise.setFailure(new IllegalStateException("ChannelPipeline does not contain " +
                       "a HttpResponseDecoder or HttpClientCodec"));
               return promise;
            }
        }

        channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {
                    ChannelPipeline p = future.channel().pipeline();
                    ChannelHandlerContext ctx = p.context(HttpRequestEncoder.class);
                    if (ctx == null) {
                        ctx = p.context(HttpClientCodec.class);
                    }
                    if (ctx == null) {
                        promise.setFailure(new IllegalStateException("ChannelPipeline does not contain " +
                                "a HttpRequestEncoder or HttpClientCodec"));
                        return;
                    }
                    p.addAfter(ctx.name(), "ws-encoder", newWebSocketEncoder());

                    promise.setSuccess();
                } else {
                    promise.setFailure(future.cause());
                }
            }
        });
        return promise;
    }
public final ChannelFuture handshake ( Channel channel , final ChannelPromise promise ) { FullHttpRequest request = newHandshakeRequest ( ) ; HttpResponseDecoder decoder = channel . pipeline ( ) . get ( HttpResponseDecoder . class ) ; if ( decoder == null ) { HttpClientCodec codec = channel . pipeline ( ) . get ( HttpClientCodec . class ) ; if ( codec == null ) { promise . setFailure ( new IllegalStateException ( "ChannelPipeline does not contain " + "a HttpResponseDecoder or HttpClientCodec" ) ) ; return promise ; } } channel . writeAndFlush ( request ) . addListener ( new ChannelFutureListener ( ) { @ Override public void operationComplete ( ChannelFuture future ) { if ( future . isSuccess ( ) ) { ChannelPipeline p = future . channel ( ) . pipeline ( ) ; ChannelHandlerContext ctx = p . context ( HttpRequestEncoder . class ) ; if ( ctx == null ) { ctx = p . context ( HttpClientCodec . class ) ; } if ( ctx == null ) { promise . setFailure ( new IllegalStateException ( "ChannelPipeline does not contain " + "a HttpRequestEncoder or HttpClientCodec" ) ) ; return ; } p . addAfter ( ctx . name ( ) , "ws-encoder" , newWebSocketEncoder ( ) ) ; promise . setSuccess ( ) ; } else { promise . setFailure ( future . cause ( ) ) ; } } } ) ; return promise ; }
Begins the opening handshake

@param channel
Channel
@param promise
the {@link ChannelPromise} to be notified when the opening handshake is sent