コード例 #1
0
ファイル: WebSocketClient.cs プロジェクト: librame/extensions
        public async Task StartAsync(Action <IChannel> configureProcess, string host = null, int?port = null)
        {
            Action <IChannel> _configureProcess = async channel =>
            {
                configureProcess.Invoke(channel);

                var handler = channel.Pipeline.Last();
                if (handler.IsNotNull())
                {
                    var webSocketHandler = handler.CastTo <IChannelHandler,
                                                           WebSocketClientHandler>(nameof(handler));

                    await webSocketHandler.HandshakeCompletion.ConfigureAwait();

                    Logger.LogInformation("WebSocket handshake completed.\n");
                    Logger.LogInformation($"\t[{_clientOptions.ExitCommand}]:Quit \n\t [ping]:Send ping frame\n\t Enter any text and Enter: Send text frame");
                }
            };

            await StartAsync(webSocketUrl =>
            {
                // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
                // If you change it to V00, ping is not supported and remember to change
                // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
                var handshaker = WebSocketClientHandshakerFactory.NewHandshaker(webSocketUrl,
                                                                                WebSocketVersion.V13, null, true, new DefaultHttpHeaders());

                return(new WebSocketClientHandler(this, handshaker));
            },
                             _configureProcess, host, port).ConfigureAwait();
        }
コード例 #2
0
    async void Connect()
    {
        var workerGroup = new MultithreadEventLoopGroup();

        // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
        // If you change it to V00, ping is not supported and remember to change
        // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
        var handler = new BilibiliLiveHandler(
            WebSocketClientHandshakerFactory.NewHandshaker(
                new Uri("ws://broadcastlv.chat.bilibili.com:2244/sub"), WebSocketVersion.V13, null, true,
                new DefaultHttpHeaders()), this);

        var bootstrap = new Bootstrap()
                        .Group(workerGroup)
                        .Option(ChannelOption.TcpNodelay, true)
                        .Channel <TcpSocketChannel>()
                        .Handler(new ActionChannelInitializer <IChannel>(channel =>
        {
            var pipeline = channel.Pipeline;
            pipeline.AddLast(new HttpClientCodec(),
                             new HttpObjectAggregator(8192),
                             WebSocketClientCompressionHandler.Instance,
                             handler);
        }));
        await bootstrap.ConnectAsync(new DnsEndPoint("broadcastlv.chat.bilibili.com", 2244));
    }
コード例 #3
0
        public WebSocketClient(string ip, int port, string path, TcpSocketCientEvent <IWebSocketClient, string> clientEvent)
            : base(ip, port, clientEvent)
        {
            string uri = $"ws://{ip}:{port}{path}";

            handshaker = WebSocketClientHandshakerFactory.NewHandshaker(
                new Uri(uri), WebSocketVersion.V13, null, true, new DefaultHttpHeaders());

            completionSource = new TaskCompletionSource();
        }
コード例 #4
0
        public async Task ConnectAsync()
        {
            try
            {
                if (group == null)
                {
                    if (_useLibuv)
                    {
                        group = new EventLoopGroup();
                    }
                    else
                    {
                        group = new MultithreadEventLoopGroup();
                    }
                }

                if (bootstrap == null)
                {
                    bootstrap = new Bootstrap();
                    bootstrap
                    .Group(group)
                    .Option(ChannelOption.TcpNodelay, true)
                    .Option(ChannelOption.ConnectTimeout, TimeSpan.FromSeconds(_timeout));

                    if (_useLibuv)
                    {
                        bootstrap.Channel <TcpChannel>();
                    }
                    else
                    {
                        bootstrap.Channel <TcpSocketChannel>();
                    }

                    bootstrap.Handler(new ActionChannelInitializer <IChannel>(ch =>
                    {
                        IChannelPipeline pipeline = ch.Pipeline;
                        _event.OnPipelineAction?.Invoke(pipeline);
                        pipeline.AddLast(new HttpClientCodec());
                        pipeline.AddLast(new HttpObjectAggregator(8192));
                        pipeline.AddLast(WebSocketClientCompressionHandler.Instance);
                        pipeline.AddLast(new WebSocketClientHandler(this, WebSocketClientHandshakerFactory.NewHandshaker(builder.Uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders())));
                    }));
                }

                await Close();

                channelWork = await bootstrap.ConnectAsync(IPAddress.Parse(builder.Host), builder.Port);
            }
            catch (Exception ex)
            {
                _event.OnCloseAction?.Invoke(ex);
            }
        }
コード例 #5
0
        public async Task StartAsync <T>() where T : IWebSocketClientHandler
        {
            if (!(Config is DotNettyClientConfig webSocketClientConfig))
            {
                throw new MateralWebSocketClientException("Config类型必须派生于DotNettyClientConfig");
            }
            WebSocketClientHandshaker webSocketClientHandshaker = WebSocketClientHandshakerFactory.NewHandshaker(webSocketClientConfig.UriBuilder.Uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders());
            var handler = ConvertManager.GetDefaultObject <T>(webSocketClientHandshaker);

            if (!(handler is DotNettyClientHandler clientHandler))
            {
                throw new MateralWebSocketClientException("Handler类型必须派生于DotNettyClientHandler");
            }
            _clientHandler = clientHandler;
            _clientHandler.SetClient(this);
            await StartAsync();
        }
コード例 #6
0
        public void ClientHandshakerForceClose()
        {
            WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.NewHandshaker(
                new Uri("ws://localhost:1234/test"), WebSocketVersion.V13, null, true,
                EmptyHttpHeaders.Default, int.MaxValue, true, false, 20);

            EmbeddedChannel serverChannel = CreateServerChannel(
                new CloseNoOpServerProtocolHandler(this, "/test"),
                new ServerHandshakeForceCloseHander(this));
            EmbeddedChannel clientChannel = CreateClientChannel(handshaker, new ClientHandshakeForceCloseHander(this, handshaker));

            // Transfer the handshake from the client to the server
            TransferAllDataWithMerge(clientChannel, serverChannel);
            // Transfer the handshake from the server to client
            TransferAllDataWithMerge(serverChannel, clientChannel);

            // Transfer closing handshake
            TransferAllDataWithMerge(clientChannel, serverChannel);
            Assert.True(_serverReceivedCloseHandshake);
            // Should not be closed yet as we disabled closing the connection on the server
            Assert.False(_clientForceClosed);

            while (!_clientForceClosed)
            {
                Thread.Sleep(10);
                // We need to run all pending tasks as the force close timeout is scheduled on the EventLoop.
                clientChannel.RunPendingTasks();
            }

            // clientForceClosed would be set to TRUE after any close,
            // so check here that force close timeout was actually fired
            Assert.True(handshaker.IsForceCloseComplete);

            // Both should be empty
            Assert.False(serverChannel.FinishAndReleaseAll());
            Assert.False(clientChannel.FinishAndReleaseAll());
        }
コード例 #7
0
        public async Task RunAsync()
        {
            OnSubMessage?.Invoke("连接服务中......", "重要");
            //第一步:创建ServerBootstrap实例
            var bootstrap = new Bootstrap();

            //第二步:绑定事件组
            workGroup = new MultithreadEventLoopGroup();
            bootstrap.Group(workGroup);
            //第三部:绑定通道
            bootstrap.Channel <TcpSocketChannel>();
            //第四步:配置处理器
            bootstrap.Option(ChannelOption.TcpNodelay, true);
            var builder = new UriBuilder
            {
                Scheme = _clientConfig.IsWss ? "wss" : "ws",
                Host   = _clientConfig.Host,
                Port   = _clientConfig.Port,
                Path   = _clientConfig.Path
            };
            WebSocketClientHandshaker clientHandshaker = WebSocketClientHandshakerFactory.NewHandshaker(builder.Uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders());
            var handler = new ClientChannelHandler(clientHandshaker);

            bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
            {
                IChannelPipeline pipeline = channel.Pipeline;
                pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(null)));
                pipeline.AddLast(
                    new HttpClientCodec(),
                    new HttpObjectAggregator(8192),
                    WebSocketClientCompressionHandler.Instance,
                    handler);
            }));
            Channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(_clientConfig.Host), _clientConfig.Port));

            await handler.HandshakeCompletion;
        }
コード例 #8
0
        static async Task RunClientAsync()
        {
            var builder = new UriBuilder
            {
                Scheme = "ws",
                Host   = "127.0.0.1",
                Port   = 18089
            };

            string path = "websocket";

            if (!string.IsNullOrEmpty(path))
            {
                builder.Path = path;
            }

            Uri uri = builder.Uri;
            //ExampleHelper.SetConsoleLogger();
            IEventLoopGroup group = new MultithreadEventLoopGroup();

            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(group)
                .Option(ChannelOption.TcpNodelay, true);

                bootstrap.Channel <TcpSocketChannel>();

                // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
                // If you change it to V00, ping is not supported and remember to change
                // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
                var handShaker = WebSocketClientHandshakerFactory.NewHandshaker(
                    uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders());
                var channelGroup = new DefaultChannelGroup(null);

                bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    pipeline.AddLast(
                        new HttpClientCodec(),
                        new HttpObjectAggregator(8192),
                        //WebSocketClientCompressionHandler.Instance,
                        new WebSocketClientProtocolHandler(handShaker, true),
                        new BinaryWebSocketFrameHandler(),
                        new ProtocolDecoder(),
                        new ProtocolEncoder(),
                        new MessageHandler(channelGroup));

                    pipeline.AddLast(new ProtocolEncoder());
                }));

                IChannel ch = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 18089));

                Console.WriteLine("WebSocket handshake completed.\n");
                Console.WriteLine("\t[bye]:Quit \n\t [ping]:Send ping frame\n\t Enter any text and Enter: Send text frame");
                while (true)
                {
                    string msg = Console.ReadLine();
                    if (msg == null)
                    {
                        break;
                    }
                    else if ("bye".Equals(msg.ToLower()))
                    {
                        await ch.WriteAndFlushAsync(new CloseWebSocketFrame());

                        break;
                    }
                    else if ("ping".Equals(msg.ToLower()))
                    {
                        var frame = new PingWebSocketFrame(Unpooled.WrappedBuffer(new byte[] { 8, 1, 8, 1 }));
                        await ch.WriteAndFlushAsync(frame);
                    }
                    else
                    {
                        //WebSocketFrame frame = new TextWebSocketFrame(msg);
                        //await ch.WriteAndFlushAsync(frame);

                        var req = new LoginValidateRequest
                        {
                            Account = "sp001",
                            Passwd  = "111",
                            ZoneId  = 4
                        };
                        await ch.WriteAndFlushAsync(req);
                    }
                }

                await ch.CloseAsync();
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: ywscr/SpanNetty
        static async Task Main(string[] args)
        {
            var builder = new UriBuilder
            {
                Scheme = ClientSettings.IsSsl ? "wss" : "ws",
                Host   = ClientSettings.Host.ToString(),
                Port   = ClientSettings.Port,
            };

            string path = ExampleHelper.Configuration["path"];

            builder.Path = !string.IsNullOrEmpty(path) ? path : WEBSOCKET_PATH;

            Uri uri = builder.Uri;

            ExampleHelper.SetConsoleLogger();

            bool useLibuv = ClientSettings.UseLibuv;

            Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket"));

            IEventLoopGroup group;

            if (useLibuv)
            {
                group = new EventLoopGroup();
            }
            else
            {
                group = new MultithreadEventLoopGroup();
            }

            X509Certificate2 cert       = null;
            string           targetHost = null;

            if (ClientSettings.IsSsl)
            {
                cert       = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
                targetHost = cert.GetNameInfo(X509NameType.DnsName, false);
            }
            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(group)
                .Option(ChannelOption.TcpNodelay, true);
                if (useLibuv)
                {
                    bootstrap.Channel <TcpChannel>();
                }
                else
                {
                    bootstrap.Channel <TcpSocketChannel>();
                }

                // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
                // If you change it to V00, ping is not supported and remember to change
                // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
                WebSocketClientHandler handler =
                    new WebSocketClientHandler(
                        WebSocketClientHandshakerFactory.NewHandshaker(
                            uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()));

                bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    if (cert != null)
                    {
                        pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)));
                    }

                    pipeline.AddLast("idleStateHandler", new IdleStateHandler(0, 0, 60));

                    pipeline.AddLast(new LoggingHandler("CONN"));
                    pipeline.AddLast(
                        new HttpClientCodec(),
                        new HttpObjectAggregator(8192),
                        WebSocketClientCompressionHandler.Instance,
                        //new WebSocketClientProtocolHandler(
                        //    webSocketUrl: uri,
                        //    version: WebSocketVersion.V13,
                        //    subprotocol: null,
                        //    allowExtensions: true,
                        //    customHeaders: new DefaultHttpHeaders(),
                        //    maxFramePayloadLength: 65536,
                        //    handleCloseFrames: true,
                        //    performMasking: false,
                        //    allowMaskMismatch: true,
                        //    enableUtf8Validator: false),
                        new WebSocketFrameAggregator(65536),
                        handler);
                }));

                try
                {
                    IChannel ch = await bootstrap.ConnectAsync(new IPEndPoint(ClientSettings.Host, ClientSettings.Port));

                    await handler.HandshakeCompletion;

                    Console.WriteLine("WebSocket handshake completed.\n");
                    Console.WriteLine("\t[bye]:Quit \n\t [ping]:Send ping frame\n\t Enter any text and Enter: Send text frame");
                    while (true)
                    {
                        string msg = Console.ReadLine();
                        if (msg == null)
                        {
                            break;
                        }
                        msg = msg.ToLowerInvariant();

                        switch (msg)
                        {
                        case "bye":
                            await ch.WriteAndFlushAsync(new CloseWebSocketFrame());

                            goto CloseLable;

                        case "ping":
                            var ping = new PingWebSocketFrame(Unpooled.WrappedBuffer(new byte[] { 8, 1, 8, 1 }));
                            await ch.WriteAndFlushAsync(ping);

                            break;

                        case "this is a test":
                            await ch.WriteAndFlushManyAsync(
                                new TextWebSocketFrame(false, "this "),
                                new ContinuationWebSocketFrame(false, "is "),
                                new ContinuationWebSocketFrame(false, "a "),
                                new ContinuationWebSocketFrame(true, "test")
                                );

                            break;

                        case "this is a error":
                            await ch.WriteAndFlushAsync(new TextWebSocketFrame(false, "this "));

                            await ch.WriteAndFlushAsync(new ContinuationWebSocketFrame(false, "is "));

                            await ch.WriteAndFlushAsync(new ContinuationWebSocketFrame(false, "a "));

                            await ch.WriteAndFlushAsync(new TextWebSocketFrame(true, "error"));

                            break;

                        default:
                            await ch.WriteAndFlushAsync(new TextWebSocketFrame(msg));

                            break;
                        }
                    }
CloseLable:
                    await ch.CloseAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    Console.WriteLine("按任意键退出");
                    Console.ReadKey();
                }
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: dovanduy/dotNetArchitect
        static async Task RunClientAsync()
        {
            var builder = new UriBuilder
            {
                Scheme = ClientSettings.IsSsl ? "wss" : "ws",
                Host   = ClientSettings.Host.ToString(),
                Port   = ClientSettings.Port
            };

            string path = ExampleHelper.Configuration["path"];

            if (!string.IsNullOrEmpty(path))
            {
                builder.Path = path;
            }

            Uri uri = builder.Uri;

            ExampleHelper.SetConsoleLogger();

            bool useLibuv = ClientSettings.UseLibuv;

            Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket"));

            IEventLoopGroup group;

            if (useLibuv)
            {
                group = new EventLoopGroup();
            }
            else
            {
                group = new MultithreadEventLoopGroup();
            }

            X509Certificate2 cert       = null;
            string           targetHost = null;

            if (ClientSettings.IsSsl)
            {
                cert       = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
                targetHost = cert.GetNameInfo(X509NameType.DnsName, false);
            }
            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(group)
                .Option(ChannelOption.TcpNodelay, true);
                if (useLibuv)
                {
                    bootstrap.Channel <TcpChannel>();
                }
                else
                {
                    bootstrap.Channel <TcpSocketChannel>();
                }

                // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
                // If you change it to V00, ping is not supported and remember to change
                // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
                var handler = new WebSocketClientHandler(
                    WebSocketClientHandshakerFactory.NewHandshaker(
                        uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()));

                bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    if (cert != null)
                    {
                        pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)));
                    }

                    pipeline.AddLast(
                        new HttpClientCodec(),
                        new HttpObjectAggregator(8192),
                        WebSocketClientCompressionHandler.Instance,
                        handler);
                }));

                IChannel ch = await bootstrap.ConnectAsync(new IPEndPoint(ClientSettings.Host, ClientSettings.Port));

                await handler.HandshakeCompletion;

                Console.WriteLine("WebSocket handshake completed.\n");
                Console.WriteLine("\t[bye]:Quit \n\t [ping]:Send ping frame\n\t Enter any text and Enter: Send text frame");
                while (true)
                {
                    string msg = Console.ReadLine();
                    if (msg == null)
                    {
                        break;
                    }
                    else if ("bye".Equals(msg.ToLower()))
                    {
                        await ch.WriteAndFlushAsync(new CloseWebSocketFrame());

                        break;
                    }
                    else if ("ping".Equals(msg.ToLower()))
                    {
                        var frame = new PingWebSocketFrame(Unpooled.WrappedBuffer(new byte[] { 8, 1, 8, 1 }));
                        await ch.WriteAndFlushAsync(frame);
                    }
                    else
                    {
                        WebSocketFrame frame = new TextWebSocketFrame(msg);
                        await ch.WriteAndFlushAsync(frame);
                    }
                }

                await ch.CloseAsync();
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
コード例 #11
0
        public Boolean Init(ConnectionListener <MQMessage> listener)
        {
            if (channel == null)
            {
                bootstrap = new Bootstrap();
                loopGroup = new MultithreadEventLoopGroup(workerThreads);
                bootstrap.Group(loopGroup);
                bootstrap.Channel <TcpSocketChannel>();
                bootstrap.Option(ChannelOption.TcpNodelay, true);
                bootstrap.Option(ChannelOption.SoKeepalive, true);

                X509Certificate2 cert = null;
                if (certificate != null && certificate.Length > 0)
                {
                    cert = CertificatesHelper.load(certificate, certificatePassword);
                }

                WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.NewHandshaker(this.getUri(), WebSocketVersion.V13, null, false, EmptyHttpHeaders.Default, 1280000);
                WebSocketClientHandler    handler    = new WebSocketClientHandler(this, handshaker, listener);

                bootstrap.Handler(new ActionChannelInitializer <ISocketChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;
                    if (isSecured)
                    {
                        if (cert != null)
                        {
                            pipeline.AddLast("ssl", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true, (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => cert), new ClientTlsSettings(address.Host, new List <X509Certificate>()
                            {
                                cert
                            })));
                        }
                        else
                        {
                            pipeline.AddLast("ssl", TlsHandler.Client(address.Host));
                        }
                    }

                    pipeline.AddLast("http - codec", new HttpClientCodec());
                    pipeline.AddLast("aggregator", new HttpObjectAggregator(65536));
                    pipeline.AddLast("handler", handler);
                    pipeline.AddLast(new ExceptionHandler());
                }));

                bootstrap.RemoteAddress(address);

                try
                {
                    Task <IChannel> task = bootstrap.ConnectAsync();
                    task.GetAwaiter().OnCompleted(() =>
                    {
                        try
                        {
                            channel = task.Result;
                        }
                        catch (Exception)
                        {
                            listener.ConnectFailed();
                            return;
                        }

                        if (channel != null)
                        {
                            listener.Connected();
                        }
                        else
                        {
                            listener.ConnectFailed();
                        }
                    });
                }
                catch (Exception)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #12
0
ファイル: WebSocketConnect.cs プロジェクト: zyj0021/CRL5
        void Start()
        {
            var builder = new UriBuilder
            {
                Scheme = "ws",
                Host   = host,
                Port   = port
            };

            string path = "websocket";

            if (!string.IsNullOrEmpty(path))
            {
                builder.Path = path;
            }

            Uri uri = builder.Uri;


            IEventLoopGroup group;

            group = new MultithreadEventLoopGroup();

            X509Certificate2 cert       = null;
            string           targetHost = null;
            //if (ClientSettings.IsSsl)
            //{
            //    cert = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
            //    targetHost = cert.GetNameInfo(X509NameType.DnsName, false);
            //}
            var bootstrap = new Bootstrap();

            bootstrap
            .Group(group)
            .Option(ChannelOption.TcpNodelay, true);
            bootstrap.Channel <TcpSocketChannel>();

            // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
            // If you change it to V00, ping is not supported and remember to change
            // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
            var handler = new WebSocketClientHandler(
                WebSocketClientHandshakerFactory.NewHandshaker(
                    uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()), allWaits, this);

            bootstrap.Handler(new ActionChannelInitializer <IChannel>(channel =>
            {
                IChannelPipeline pipeline = channel.Pipeline;
                //if (cert != null)
                //{
                //    pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)));
                //}

                pipeline.AddLast(
                    new HttpClientCodec(),
                    new HttpObjectAggregator(8192),
                    WebSocketClientCompressionHandler.Instance,
                    handler);
            }));

            channel = bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(host), port)).Result;
            handler.HandshakeCompletion.Wait();

            Console.WriteLine("WebSocket handshake completed.");

            pingWork = new CRL.Core.ThreadWork();
        }