// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.1
        private static async System.Threading.Tasks.Task GetTableAsync(
            Microsoft.AspNetCore.Http.HttpContext context
            , System.Net.WebSockets.WebSocket webSocket)
        {
            WebSocketTextWriter wtw = new WebSocketTextWriter(webSocket);

            byte[] buffer = new byte[1024 * 4];
            System.Net.WebSockets.WebSocketReceiveResult result = await webSocket.ReceiveAsync(
                new System.ArraySegment <byte>(buffer)
                , System.Threading.CancellationToken.None
                );


            SqlService service = (SqlService)context.RequestServices.GetService(typeof(SqlService));

            while (!result.CloseStatus.HasValue)
            {
                //string answer = @"The server received the following message: ";
                //byte[] answerBuffer = System.Text.Encoding.UTF8.GetBytes(answer);

                //await webSocket.SendAsync(
                //      new ArraySegment<byte>(answerBuffer, 0, answerBuffer.Length)
                //    , System.Net.WebSockets.WebSocketMessageType.Text
                //    , false, System.Threading.CancellationToken.None
                //);

                //wtw.WriteLine("Test 123");
                //wtw.Transmit();
                //await System.Threading.Tasks.Task.Delay(30);



                await SqlServiceJsonHelper.AnyDataReaderToJson("SELECT * FROM T_Benutzer", null, service, wtw, RenderType_t.DataTable);

                await wtw.TransmitAsync();


                //await System.Threading.Tasks.Task.Delay(3000);
                //wtw.WriteLine("Test 456");
                //wtw.Transmit();
                //await System.Threading.Tasks.Task.Delay(30);


                //using (Newtonsoft.Json.JsonTextWriter jsonWriter =
                //    new Newtonsoft.Json.JsonTextWriter(wtw))
                //{

                //}

                result = await webSocket.ReceiveAsync(
                    new System.ArraySegment <byte>(buffer)
                    , System.Threading.CancellationToken.None
                    );
            } // Whend

            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, System.Threading.CancellationToken.None);
        } // End Task GetTableAsync
Beispiel #2
0
        // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.1
        private static async System.Threading.Tasks.Task Echo(
            Microsoft.AspNetCore.Http.HttpContext context
            , System.Net.WebSockets.WebSocket webSocket)
        {
            WebSocketTextWriter wtw = new WebSocketTextWriter(webSocket);

            byte[] buffer = new byte[1024 * 4];
            System.Net.WebSockets.WebSocketReceiveResult result = await webSocket.ReceiveAsync(
                new System.ArraySegment <byte>(buffer)
                , System.Threading.CancellationToken.None
                );


            while (!result.CloseStatus.HasValue)
            {
                //string answer = @"The server received the following message: ";
                //byte[] answerBuffer = System.Text.Encoding.UTF8.GetBytes(answer);

                //await webSocket.SendAsync(
                //      new ArraySegment<byte>(answerBuffer, 0, answerBuffer.Length)
                //    , System.Net.WebSockets.WebSocketMessageType.Text
                //    , false, System.Threading.CancellationToken.None
                //);

                wtw.WriteLine("Test 123");
                await wtw.TransmitAsync();

                wtw.WriteLine("Test 456");
                await wtw.TransmitAsync();

                wtw.WriteLine("Echo: ");
                await wtw.FlushAsync();

                wtw.Write(@"The server received the following message: ");
                await wtw.FlushAsync();

                // wtw.Send(false, new byte[0]);

                await webSocket.SendAsync(
                    new System.ArraySegment <byte>(buffer, 0, result.Count)
                    , result.MessageType
                    , result.EndOfMessage
                    , System.Threading.CancellationToken.None
                    );

                result = await webSocket.ReceiveAsync(
                    new System.ArraySegment <byte>(buffer)
                    , System.Threading.CancellationToken.None
                    );
            } // Whend

            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, System.Threading.CancellationToken.None);
        } // End Task Echo
Beispiel #3
0
        /// <summary>
        /// On receiving data handler.
        /// </summary>
        /// <param name="data">The data received.</param>
        /// <param name="result">The received result.</param>
        private void ReceiveHandler(byte[] data, System.Net.WebSockets.WebSocketReceiveResult result)
        {
            // If data exists.
            if (data != null && data.Length > 0)
            {
                // Write the buffer.
                _writeStream.Write(data, 0, result.Count);
            }

            // Is the end of the data.
            if (result.EndOfMessage)
            {
                // Got translation.
                OnTranslationReceived?.Invoke(this, new EventArgs());
            }
        }
Beispiel #4
0
        private static async System.Threading.Tasks.Task <T> DeserializeJSON <T>(
            System.Net.WebSockets.WebSocket webSocket
            , Newtonsoft.Json.JsonSerializer serializer)
        {
            T searchArguments = default(T);

            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                byte[] buffer = new byte[1024 * 4];
                System.Net.WebSockets.WebSocketReceiveResult result = null;

                do
                {
                    result = await webSocket.ReceiveAsync(
                        new System.ArraySegment <byte>(buffer)
                        , System.Threading.CancellationToken.None
                        );

                    ms.Write(buffer, 0, result.Count);
                } while (!result.EndOfMessage);

                // string json = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                // searchArguments = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchArguments>(json);

                ms.Position = 0;


                using (System.IO.TextReader tr = new System.IO.StreamReader(ms, System.Text.Encoding.UTF8))
                {
                    using (Newtonsoft.Json.JsonReader jsonReader = new Newtonsoft.Json.JsonTextReader(tr))
                    {
                        try
                        {
                            searchArguments = serializer.Deserialize <T>(jsonReader);
                        }
                        catch (System.Exception ex)
                        {
                            System.Console.WriteLine(ex.Message);
                        }
                    } // End Using jsonReader
                }     // End Using tr
            }         // End Using ms

            return(searchArguments);
        } // End Task DeserializeJSON
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc();

            app.UseWebSockets();

            app.Use(async(http, next) =>
            {
                if (http.WebSockets.IsWebSocketRequest && http.Request.Path == "/ws")
                {
                    Program.wb = await http.WebSockets.AcceptWebSocketAsync();
                    await Task.Run(async() =>
                    {
                        while (Program.wb.State == System.Net.WebSockets.WebSocketState.Open)
                        {
                            byte[] bt = new byte[1024];
                            System.Net.WebSockets.WebSocketReceiveResult rc = await Program.wb.ReceiveAsync(bt, CancellationToken.None);

                            await Program.wb.SendAsync(bt, System.Net.WebSockets.WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    });
                }
                else
                {
                    await next();
                }
            });
        }
Beispiel #6
0
        private static async System.Threading.Tasks.Task Prototype201802084_1()
        {
            // todo We need exception handling here.

            {
                double dateTimeFrequencyToPhaseFrequencyRatio =
                    (double)System.TimeSpan.TicksPerSecond / (double)System.Diagnostics.Stopwatch.Frequency;
                long basePhase = System.Diagnostics.Stopwatch.GetTimestamp();
                long baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks;
                basePhase = System.Diagnostics.Stopwatch.GetTimestamp();
                baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks;

                var clientWebSocket = new System.Net.WebSockets.ClientWebSocket();
                //System.Threading.Tasks.Task task =
                await
                clientWebSocket.ConnectAsync
                    (new System.Uri
                    //(@"wss://ws-feed-public.sandbox.gdax.com"),
                        (@"wss://ws-feed.gdax.com"),
                    System.Threading.CancellationToken.None
                    );

                // todo ??? The caller really should do this if needed.
                // todo ??? But any method really should do this
                // todo ??? if after {await} it's not supposed to return to the synchronization context.
                //// todo Comment in other places where we don't call this.
                //.ConfigureAwait(false);
                //int timeSpanInMilliSeconds = System.Environment.TickCount;

                // todo Remember to call this even if the task already completed -- to rethrow any exceptions.
                // todo {task.Result} also waits, right?
                //task.Wait();

                //task.RunSynchronously();
                //timeSpanInMilliSeconds = System.Environment.TickCount - timeSpanInMilliSeconds;

                //>>>clientWebSocket.ReceiveAsync

                if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    // todo Prototype subscribe/unsubscribe for 1 instrument at a time.

                    const string channelName =
                        //@"heartbeat";
                        //@"ticker";
                        @"level2";
                    //@"user";
                    //@"matches";
                    //@"full";

                    const string requestString =
                        //Newtonsoft.Json.JsonConvert.SerializeObject
                        //   ( new
                        //      {
                        //         type = "subscribe",
                        //         product_ids = new string[] { @"ETH-USD", @"ETH-EUR", },
                        //      }
                        //   );
                        "{" +
                        "\"type\":\"subscribe\"," +
                        "\"channels\":[{\"name\":\"" + channelName + "\",\"product_ids\":[\"BTC-USD\",\"BTC-EUR\"]}]" +
                        "}";

                    byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString);
                    await clientWebSocket.SendAsync
                        (new System.ArraySegment <byte>(requestBytes),

                        // todo ??? Binary didn't work, right?
                        System.Net.WebSockets.WebSocketMessageType.Text,
                        //System.Net.WebSockets.WebSocketMessageType.Binary,

                        true,
                        System.Threading.CancellationToken.None
                        );

                    // todo This really doesn't need to be more than 16K, right?
                    var receiveBuffer = new System.ArraySegment <byte>(new byte[33 * 1024]);

                    for (bool isMessageBegin = true; ;)
                    {
                        if (clientWebSocket.State != System.Net.WebSockets.WebSocketState.Open)
                        {
                            System.Console.WriteLine(@"201802085");
                            break;
                        }
                        else
                        {
                        }

                        System.Net.WebSockets.WebSocketReceiveResult webSocketReceiveResult =
                            await clientWebSocket.ReceiveAsync(receiveBuffer, System.Threading.CancellationToken.None);

                        // todo ???
                        if (webSocketReceiveResult.Count <= 0)
                        {
                            System.Console.WriteLine(@"201802086");
                            break;
                        }
                        else
                        {
                        }

                        if (isMessageBegin)
                        {
                            isMessageBegin = false;
                            System.Console.WriteLine(',');
                            //System.Console.WriteLine();
                            long currentUtcDateTimeInTicks =
                                (long)((double)(ulong)(System.Diagnostics.Stopwatch.GetTimestamp() - basePhase) * dateTimeFrequencyToPhaseFrequencyRatio + 0.5) +
                                baseUtcDateTimeInTicks;
                            System.Console.Write
                                ((new System.DateTime(currentUtcDateTimeInTicks)).ToString(@"o", System.Globalization.DateTimeFormatInfo.InvariantInfo));
                        }
                        else
                        {
                        }

                        string string1 =
                            System.Text.Encoding.ASCII.GetString(receiveBuffer.Array, 0, webSocketReceiveResult.Count);
                        System.Console.Write(string1);

                        if (webSocketReceiveResult.MessageType == System.Net.WebSockets.WebSocketMessageType.Close)
                        {
                            System.Console.WriteLine(@"201802087");
                            break;
                        }
                        else
                        {
                        }

                        if (webSocketReceiveResult.EndOfMessage)
                        {
                            isMessageBegin = true;
                            //break;
                        }
                        else
                        {
                        }
                    }
                }
                else
                {
                    System.Console.WriteLine(@"201802088");
                }

                // todo ??? WebSocketState >= CloseSent

                clientWebSocket.Dispose();
            }

            StaticBool1_ = true;
        }
Beispiel #7
0
        public async void conectar(bool enBaseDatos = true)
        {
            try {
                await cliente.ConnectAsync(new Uri("ws://irc-ws.chat.twitch.tv"), cancellationToken);

                if (cliente.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    byte[]   bufferByte = new byte[6000];
                    int      estado     = 0;
                    string[] ESPERAS    = { ":tmi.twitch.tv 376 " + canal + " :>", ":End of /NAMES list" };
                    System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"(.*)\!(.*)@(.*)\.tmi\.twitch\.tv (PRIVMSG|PART) #(.*) :(.*)", System.Text.RegularExpressions.RegexOptions.RightToLeft);

                    ArraySegment <byte> buffer = new ArraySegment <byte>(bufferByte);
                    await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("PASS oauth:" + oauth)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);

                    await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("NICK " + canal)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);

                    //cliente.Options.
                    //a cliente.ReceiveAsync(buffer, cancellationToken);
                    //envioDatos.
                    System.Net.WebSockets.WebSocketReceiveResult resultado = await cliente.ReceiveAsync(buffer, cancellationToken);

                    while (cliente.State == System.Net.WebSockets.WebSocketState.Open)
                    {
                        string[] respuestas = arrayString(bufferByte, resultado.Count).Replace("\n", "\r").Replace("\r\r", "\r").Split('\r');
                        for (int i = 0; i < respuestas.Length; i++)
                        {
                            string respuesta = respuestas[i];
                            if (respuesta == ESPERAS[0])
                            {
                                estado++;
                            }
                            string mensaje = "";
                            if (respuesta.Length > 0)
                            {
                                switch (estado)
                                {
                                case 1:
                                    estado++;
                                    mensaje = "JOIN #" + canal;
                                    await cliente.SendAsync(new ArraySegment <byte>(arrayBytes(mensaje)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);

                                    break;
                                }
                                if (respuesta == "PING :tmi.twitch.tv")
                                {
                                    await cliente.SendAsync(new ArraySegment <byte>(arrayBytes("PONG :tmi.twitch.tv")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);
                                }
                                else
                                {
                                    if (estado > 0)
                                    {
                                        //System.Diagnostics.Trace.WriteLine(respuesta);
                                        //System.Diagnostics.Trace.WriteLine(toxicidad(respuesta));
                                        while (mensajesEnviar.Count > 0)
                                        {
                                            string mensajeTexto = "PRIVMSG #" + Configuracion.parametro("canal") + " :" + mensajesEnviar[0];
                                            await cliente.SendAsync(new ArraySegment <byte>(arrayBytes(mensajeTexto)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);

                                            mensajesEnviar.RemoveAt(0);
                                        }
                                        System.Text.RegularExpressions.Match coincidencias = regEx.Match(respuesta);
                                        if (coincidencias.Success)
                                        {
                                            string[] partes = regEx.GetGroupNames();
                                            //System.Text.RegularExpressions.Group grp

                                            /*foreach (string nombre in partes) {
                                             * System.Text.RegularExpressions.Group grp = coincidencias.Groups[nombre];
                                             * //Console.WriteLine("   {0}: '{1}'", name, grp.Value);
                                             * }*/
                                            System.Diagnostics.Trace.WriteLine((coincidencias.Groups["0"].Value));
                                            System.Diagnostics.Trace.WriteLine("" + (coincidencias.Groups["2"].Value) + " = " + (coincidencias.Groups["6"].Value));
                                            string aliasUsuario = coincidencias.Groups["2"].Value.ToLower();
                                            long   idUsuario    = -1;
                                            try {
                                                Datos usuarios = BD.consulta("select id,avatar from usuarios where alias='" + aliasUsuario + "'");
                                                if (usuarios.Length == 0)
                                                {
                                                    String avatar  = null;
                                                    JSON   usuario = infoUsuario(aliasUsuario);
                                                    try {
                                                        avatar = usuario["data"][0]["profile_image_url"].ToString();
                                                    } catch { }

                                                    int numeroAfectados = BD.ejecutar("insert into usuarios (alias, avatar, nombre, userID) values ('" + aliasUsuario + "'," + (avatar != null ? "'" + avatar + "'" : "null") + ",'" + usuario["data"][0]["display_name"].ToString() + "','" + usuario["data"][0]["id"].ToString() + "')");
                                                    if (numeroAfectados == 1)
                                                    {
                                                        idUsuario = BD.id;
                                                    }
                                                }
                                                else
                                                {
                                                    if (usuarios[0]["avatar"] == null || usuarios[0]["avatar"].ToString().Length == 0)
                                                    {
                                                        JSON   usuario = infoUsuario(aliasUsuario);
                                                        string avatar  = usuario["data"][0]["profile_image_url"].ToString();
                                                        BD.ejecutar("update usuarios set avatar='" + avatar + "' where alias='" + aliasUsuario + "'");
                                                    }
                                                    idUsuario = long.Parse(usuarios[0]["id"].ToString());
                                                }
                                                string texto      = coincidencias.Groups["6"].Value;
                                                double puntuacion = toxicidad(texto);

                                                texto = tratarMensaje(texto, puntuacion);
                                                if (enBaseDatos)
                                                {
                                                    try {
                                                        texto = texto.Replace("\"", "\\\"").Replace("'", "''");
                                                        BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1," + idUsuario + ", '" + texto + "'," + puntuacion.ToString().Replace(",", ".") + ")");
                                                    }catch (Exception ex1) {
                                                        BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1," + idUsuario + ", '" + aUTF8(texto) + "'," + puntuacion.ToString().Replace(",", ".") + ")");
                                                    }
                                                }
                                            } catch (Exception ex) {
                                                LOG.debug(ex.Message, "Conectar a twitch");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        resultado = await cliente.ReceiveAsync(buffer, cancellationToken);
                    }
                    //resultado.
                    //System.Diagnostics.Trace.WriteLine(arrayString(bufferByte));
                }
            } catch (Exception ex) {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
        }
Beispiel #8
0
        public async void conectarTopicos(bool enBaseDatos = true)
        {
            try {
                await clienteTopic.ConnectAsync(new Uri("wss://pubsub-edge.twitch.tv"), cancellationToken2);

                if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    byte[]   bufferByte = new byte[6000];
                    int      estado     = 0;
                    string[] ESPERAS    = { "{ \"type\": \"PONG\" }", ":End of /NAMES list" };
                    System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"(.*)\!(.*)@(.*)\.tmi\.twitch\.tv (PRIVMSG|PART) #(.*) :(.*)", System.Text.RegularExpressions.RegexOptions.RightToLeft);

                    ArraySegment <byte>        buffer = new ArraySegment <byte>(bufferByte);
                    System.Windows.Forms.Timer ping   = new System.Windows.Forms.Timer();
                    ping.Interval = 15000;
                    ping.Enabled  = true;
                    ping.Tick    += async(object sender, EventArgs e) => {
                        if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open)
                        {
                            await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"PING\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2);
                        }
                        else
                        {
                            //await clienteTopic.CloseAsync();
                            await clienteTopic.ConnectAsync(new Uri("wss://pubsub-edge.twitch.tv"), cancellationToken2);

                            if (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open)
                            {
                                await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"RECONNECT\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2);
                            }
                        }
                    };

                    /*await cliente.SendAsync(new ArraySegment<byte>(arrayBytes("NICK " + canal)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken);*/
                    await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes("{\"type\":\"PING\"}")), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2);

                    System.Net.WebSockets.WebSocketReceiveResult resultado = await clienteTopic.ReceiveAsync(buffer, cancellationToken2);

                    while (clienteTopic.State == System.Net.WebSockets.WebSocketState.Open)
                    {
                        string[] respuestas = arrayString(bufferByte, resultado.Count).Replace("\n", "\r").Replace("\r\r", "\r").Split('\r');
                        for (int i = 0; i < respuestas.Length; i++)
                        {
                            string respuesta = respuestas[i];
                            string mensaje   = "";
                            if (respuesta.Length > 0)
                            {
                                switch (estado)
                                {
                                case 0:
                                    estado++;
                                    mensaje = "{\"type\":\"LISTEN\",\"nonce\":\"\",\"data\":{\"topics\": [\"channel-bits-events-v2." + Configuracion.parametro("id_usuario") + "\",\"whispers." + Configuracion.parametro("id_usuario") + "\",\"channel-subscribe-events-v1." + Configuracion.parametro("id_usuario") + "\"],\"auth_token\": \"" + Configuracion.parametro("oauth") + "\"}}";
                                    await clienteTopic.SendAsync(new ArraySegment <byte>(arrayBytes(mensaje)), System.Net.WebSockets.WebSocketMessageType.Text, true, cancellationToken2);

                                    break;

                                case 1:
                                    if (respuesta != ESPERAS[0])
                                    {
                                        JSON respuestaJSON = new JSON();
                                        respuestaJSON.parse(respuesta);
                                        switch (respuestaJSON["type"].ToString())
                                        {
                                        case "MESSAGE":
                                            if (respuestaJSON["data"]["topic"].ToString() == "whispers." + Configuracion.parametro("id_usuario"))
                                            {
                                                string texto      = ((Entidad)respuestaJSON["data"]["message"])["body"].ToString();
                                                double puntuacion = toxicidad(texto);

                                                tratarMensaje(texto, puntuacion);
                                                if (enBaseDatos)
                                                {
                                                    BD.ejecutar("insert into mensajes (idEstado, idUsuario, mensaje,puntuacion) values (1,1, '" + texto.Replace("\"", "\\\"") + "'," + puntuacion.ToString().Replace(",", ".") + ")");
                                                }
                                            }
                                            break;
                                        }

                                        System.IO.File.AppendAllText("sucripcion.txt", respuesta + "\r\n");
                                    }

                                    break;
                                }
                            }
                        }
                        try {
                            resultado = await clienteTopic.ReceiveAsync(buffer, cancellationToken);
                        } catch (Exception ex1) {
                            System.Diagnostics.Trace.WriteLine(ex1.Message);
                        }
                    }
                    //resultado.
                    //System.Diagnostics.Trace.WriteLine(arrayString(bufferByte));
                }
            } catch (Exception ex) {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Invoked when this handler is determined to be the best suited to handle the supplied connection.
        /// </summary>
        /// <param name="context">
        /// The HTTP context.
        /// </param>
        /// <returns>
        /// The handling task.
        /// </returns>
        public override async Task Handle(HttpContext context)
        {
            ClientWebSocket wsServer = null;

            System.Net.WebSockets.WebSocket wsClient = null;

            try
            {
                // First we need the URL for this connection, since it's been requested to be
                // upgraded to a websocket.

                var connFeature = context.Features.Get <IHttpRequestFeature>();

                string fullUrl = string.Empty;

                if (connFeature != null && connFeature.RawTarget != null && !string.IsNullOrEmpty(connFeature.RawTarget) && !(string.IsNullOrWhiteSpace(connFeature.RawTarget)))
                {
                    fullUrl = $"{context.Request.Scheme}://{context.Request.Host}{connFeature.RawTarget}";
                }
                else
                {
                    fullUrl = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}";
                }

                // Need to replate the scheme with appropriate websocket scheme.
                if (fullUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
                {
                    fullUrl = "ws://" + fullUrl.Substring(7);
                }
                else if (fullUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                {
                    fullUrl = "wss://" + fullUrl.Substring(8);
                }

                // Next we need to try and parse the URL as a URI, because the websocket client
                // requires this for connecting upstream.

                if (!Uri.TryCreate(fullUrl, UriKind.RelativeOrAbsolute, out Uri wsUri))
                {
                    LoggerProxy.Default.Error("Failed to parse websocket URI.");
                    return;
                }

                // Create the websocket that's going to connect to the remote server.
                wsServer = new ClientWebSocket();
                wsServer.Options.Cookies = new System.Net.CookieContainer();
                //wsServer.Options.SetBuffer((int)ushort.MaxValue * 16, (int)ushort.MaxValue * 16);

                foreach (var proto in context.WebSockets.WebSocketRequestedProtocols)
                {
                    wsServer.Options.AddSubProtocol(proto);
                }

                foreach (var hdr in context.Request.Headers)
                {
                    if (!ForbiddenWsHeaders.IsForbidden(hdr.Key))
                    {
                        try
                        {
                            wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString());
                        }
                        catch (Exception hdrException)
                        {
                            LoggerProxy.Default.Error(hdrException);
                        }
                    }
                }

                foreach (var cookie in context.Request.Cookies)
                {
                    try
                    {
                        wsServer.Options.Cookies.Add(new Uri(fullUrl, UriKind.Absolute), new System.Net.Cookie(cookie.Key, System.Net.WebUtility.UrlEncode(cookie.Value)));
                    }
                    catch (Exception e)
                    {
                        LoggerProxy.Default.Error("Error while attempting to add websocket cookie.");
                        LoggerProxy.Default.Error(e);
                    }
                }

                if (context.Connection.ClientCertificate != null)
                {
                    wsServer.Options.ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection(new[] { context.Connection.ClientCertificate.ToV2Certificate() });
                }

                // Connect the server websocket to the upstream, remote webserver.
                await wsServer.ConnectAsync(wsUri, context.RequestAborted);

                foreach (string key in wsServer.ResponseHeaders)
                {
                    if (!ForbiddenWsHeaders.IsForbidden(key))
                    {
                        try
                        {
                            var value = wsServer.ResponseHeaders[key];
                            context.Response.Headers[key] = wsServer.ResponseHeaders[key];
                        }
                        catch (Exception hdrException)
                        {
                            LoggerProxy.Default.Error(hdrException);
                        }
                    }
                }

                // Create, via acceptor, the client websocket. This is the local machine's websocket.
                wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null);

                // Match the HTTP version of the client on the upstream request. We don't want to
                // transparently pass around headers that are wrong for the client's HTTP version.
                Version upstreamReqVersionMatch = null;

                Match match = s_httpVerRegex.Match(context.Request.Protocol);
                if (match != null && match.Success)
                {
                    upstreamReqVersionMatch = Version.Parse(match.Value);
                }

                var msgNfo = new HttpMessageInfo
                {
                    Url             = wsUri,
                    Method          = new HttpMethod(context.Request.Method),
                    IsEncrypted     = context.Request.IsHttps,
                    Headers         = context.Request.Headers.ToNameValueCollection(),
                    HttpVersion     = upstreamReqVersionMatch ?? new Version(1, 0),
                    MessageProtocol = MessageProtocol.WebSocket,
                    MessageType     = MessageType.Request,
                    RemoteAddress   = context.Connection.RemoteIpAddress,
                    RemotePort      = (ushort)context.Connection.RemotePort,
                    LocalAddress    = context.Connection.LocalIpAddress,
                    LocalPort       = (ushort)context.Connection.LocalPort
                };

                _configuration.NewHttpMessageHandler?.Invoke(msgNfo);

                switch (msgNfo.ProxyNextAction)
                {
                case ProxyNextAction.DropConnection:
                {
                    await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);

                    return;
                }
                }

                var serverMessageInfo = new HttpMessageInfo
                {
                    Url             = wsUri,
                    MessageId       = msgNfo.MessageId,
                    Method          = new HttpMethod(context.Request.Method),
                    IsEncrypted     = context.Request.IsHttps,
                    Headers         = context.Request.Headers.ToNameValueCollection(),
                    HttpVersion     = upstreamReqVersionMatch ?? new Version(1, 0),
                    MessageProtocol = MessageProtocol.WebSocket,
                    MessageType     = MessageType.Response,
                    RemoteAddress   = context.Connection.RemoteIpAddress,
                    RemotePort      = (ushort)context.Connection.RemotePort,
                    LocalAddress    = context.Connection.LocalIpAddress,
                    LocalPort       = (ushort)context.Connection.LocalPort
                };

                var clientMessageInfo = new HttpMessageInfo
                {
                    Url             = wsUri,
                    MessageId       = msgNfo.MessageId,
                    IsEncrypted     = context.Request.IsHttps,
                    Headers         = context.Request.Headers.ToNameValueCollection(),
                    HttpVersion     = upstreamReqVersionMatch ?? new Version(1, 0),
                    MessageProtocol = MessageProtocol.WebSocket,
                    MessageType     = MessageType.Request,
                    RemoteAddress   = context.Connection.RemoteIpAddress,
                    RemotePort      = (ushort)context.Connection.RemotePort,
                    LocalAddress    = context.Connection.LocalIpAddress,
                    LocalPort       = (ushort)context.Connection.LocalPort
                };

                bool inspect = true;

                switch (msgNfo.ProxyNextAction)
                {
                case ProxyNextAction.AllowAndIgnoreContent:
                case ProxyNextAction.AllowAndIgnoreContentAndResponse:
                {
                    inspect = false;
                }
                break;
                }

                // Spawn an async task that will poll the remote server for data in a loop, and then
                // write any data it gets to the client websocket.
                var serverTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult serverResult = null;
                    var serverBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        serverResult = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);

                        while (looping && !serverResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            if (inspect)
                            {
                                serverMessageInfo.Body = new Memory <byte>(serverBuffer, 0, serverResult.Count);

                                switch (serverResult.MessageType)
                                {
                                case System.Net.WebSockets.WebSocketMessageType.Binary:
                                    {
                                        serverMessageInfo.BodyContentType = s_octetStreamContentType;
                                    }
                                    break;

                                case System.Net.WebSockets.WebSocketMessageType.Text:
                                    {
                                        serverMessageInfo.BodyContentType = s_plainTextContentType;
                                    }
                                    break;
                                }

                                _configuration.HttpMessageWholeBodyInspectionHandler?.Invoke(serverMessageInfo);
                            }

                            switch (serverMessageInfo.ProxyNextAction)
                            {
                            case ProxyNextAction.DropConnection:
                                {
                                    looping = false;
                                }
                                break;

                            default:
                                {
                                    await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverResult.Count), serverResult.MessageType, serverResult.EndOfMessage, context.RequestAborted);

                                    if (!wsClient.CloseStatus.HasValue)
                                    {
                                        serverResult = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);
                                        continue;
                                    }
                                }
                                break;
                            }

                            looping = false;
                        }

                        await wsClient.CloseAsync(serverResult.CloseStatus.Value, serverResult.CloseStatusDescription, context.RequestAborted);
                    }
                    catch (Exception err)
                    {
                        LoggerProxy.Default.Error(err);
                        try
                        {
                            var closeStatus  = serverResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = serverResult?.CloseStatusDescription ?? string.Empty;

                            await wsClient.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Spawn an async task that will poll the local client websocket, in a loop, and then
                // write any data it gets to the remote server websocket.
                var clientTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult clientResult = null;
                    var clientBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);

                        while (looping && !clientResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            if (inspect)
                            {
                                clientMessageInfo.Body = new Memory <byte>(clientBuffer, 0, clientResult.Count);

                                switch (clientResult.MessageType)
                                {
                                case System.Net.WebSockets.WebSocketMessageType.Binary:
                                    {
                                        clientMessageInfo.BodyContentType = s_octetStreamContentType;
                                    }
                                    break;

                                case System.Net.WebSockets.WebSocketMessageType.Text:
                                    {
                                        clientMessageInfo.BodyContentType = s_plainTextContentType;
                                    }
                                    break;
                                }

                                _configuration.HttpMessageWholeBodyInspectionHandler?.Invoke(clientMessageInfo);
                            }

                            switch (clientMessageInfo.ProxyNextAction)
                            {
                            case ProxyNextAction.DropConnection:
                                {
                                    looping = false;
                                }
                                break;

                            default:
                                {
                                    await wsServer.SendAsync(new ArraySegment <byte>(clientBuffer, 0, clientResult.Count), clientResult.MessageType, clientResult.EndOfMessage, context.RequestAborted);

                                    if (!wsServer.CloseStatus.HasValue)
                                    {
                                        clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);
                                        continue;
                                    }
                                }
                                break;
                            }

                            looping = false;
                        }

                        await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted);
                    }
                    catch (Exception err)
                    {
                        LoggerProxy.Default.Error(err);
                        try
                        {
                            var closeStatus  = clientResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = clientResult?.CloseStatusDescription ?? string.Empty;

                            await wsServer.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Above, we have created a bridge between the local and remote websocket. Wait for
                // both associated tasks to complete.
                await Task.WhenAll(serverTask, clientTask);
            }
            catch (Exception wshe)
            {
                LoggerProxy.Default.Error(wshe);
            }
            finally
            {
                if (wsClient != null)
                {
                    wsClient.Dispose();
                    wsClient = null;
                }

                if (wsServer != null)
                {
                    wsServer.Dispose();
                    wsServer = null;
                }
            }
        }
        public override async Task Handle(HttpContext context)
        {
            ClientWebSocket wsServer = null;

            System.Net.WebSockets.WebSocket wsClient = null;

            try
            {
                // First we need the URL for this connection, since it's been requested to be upgraded to
                // a websocket.
                var fullUrl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request);

                // Need to replate the scheme with appropriate websocket scheme.
                if (fullUrl.StartsWith("http://"))
                {
                    fullUrl = "ws://" + fullUrl.Substring(7);
                }
                else if (fullUrl.StartsWith("https://"))
                {
                    fullUrl = "wss://" + fullUrl.Substring(8);
                }

                // Next we need to try and parse the URL as a URI, because the websocket client requires
                // this for connecting upstream.

                if (!Uri.TryCreate(fullUrl, UriKind.RelativeOrAbsolute, out Uri wsUri))
                {
                    LoggerProxy.Default.Error("Failed to parse websocket URI.");
                    return;
                }

                // Create the websocket that's going to connect to the remote server.
                wsServer = new ClientWebSocket();
                wsServer.Options.Cookies = new System.Net.CookieContainer();
                wsServer.Options.SetBuffer((int)ushort.MaxValue * 16, (int)ushort.MaxValue * 16);

                foreach (var cookie in context.Request.Cookies)
                {
                    try
                    {
                        wsServer.Options.Cookies.Add(new Uri(fullUrl, UriKind.Absolute), new System.Net.Cookie(cookie.Key, System.Net.WebUtility.UrlEncode(cookie.Value)));
                    }
                    catch (Exception e)
                    {
                        LoggerProxy.Default.Error("Error while attempting to add websocket cookie.");
                        LoggerProxy.Default.Error(e);
                    }
                }

                if (context.Connection.ClientCertificate != null)
                {
                    wsServer.Options.ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection(new[] { context.Connection.ClientCertificate.ToV2Certificate() });
                }

                var reqHeaderBuilder = new StringBuilder();
                foreach (var hdr in context.Request.Headers)
                {
                    if (!ForbiddenWsHeaders.IsForbidden(hdr.Key))
                    {
                        reqHeaderBuilder.AppendFormat("{0}: {1}\r\n", hdr.Key, hdr.Value.ToString());

                        try
                        {
                            wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString());
                            Console.WriteLine("Set Header: {0} ::: {1}", hdr.Key, hdr.Value.ToString());
                        }
                        catch (Exception hdrException)
                        {
                            Console.WriteLine("Failed Header: {0} ::: {1}", hdr.Key, hdr.Value.ToString());
                            LoggerProxy.Default.Error(hdrException);
                        }
                    }
                }

                reqHeaderBuilder.Append("\r\n");

                LoggerProxy.Default.Info(string.Format("Connecting websocket to {0}", wsUri.AbsoluteUri));

                // Connect the server websocket to the upstream, remote webserver.
                await wsServer.ConnectAsync(wsUri, context.RequestAborted);

                LoggerProxy.Default.Info(String.Format("Connected websocket to {0}", wsUri.AbsoluteUri));

                // Create, via acceptor, the client websocket. This is the local machine's websocket.
                wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null);

                ProxyNextAction nxtAction = ProxyNextAction.AllowAndIgnoreContentAndResponse;
                string          customResponseContentType = string.Empty;
                byte[]          customResponse            = null;
                m_msgBeginCb?.Invoke(wsUri, reqHeaderBuilder.ToString(), null, context.Request.IsHttps ? MessageType.SecureWebSocket : MessageType.WebSocket, MessageDirection.Request, out nxtAction, out customResponseContentType, out customResponse);

                switch (nxtAction)
                {
                case ProxyNextAction.DropConnection:
                {
                    if (customResponse != null)
                    {
                    }

                    await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);

                    return;
                }
                }

                // Spawn an async task that will poll the remote server for data in a loop, and then
                // write any data it gets to the client websocket.
                var serverTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult serverStatus = null;
                    var serverBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);

                        while (looping && !serverStatus.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverStatus.Count), serverStatus.MessageType, serverStatus.EndOfMessage, context.RequestAborted);

                            if (!wsClient.CloseStatus.HasValue)
                            {
                                serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);
                                continue;
                            }

                            looping = false;
                        }

                        await wsClient.CloseAsync(serverStatus.CloseStatus.Value, serverStatus.CloseStatusDescription, context.RequestAborted);
                    }
                    catch
                    {
                        try
                        {
                            var closeStatus  = serverStatus?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = serverStatus?.CloseStatusDescription ?? string.Empty;

                            await wsClient.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Spawn an async task that will poll the local client websocket, in a loop, and then
                // write any data it gets to the remote server websocket.
                var clientTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult clientResult = null;
                    var clientBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);

                        while (looping && !clientResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            await wsServer.SendAsync(new ArraySegment <byte>(clientBuffer, 0, clientResult.Count), clientResult.MessageType, clientResult.EndOfMessage, context.RequestAborted);

                            if (!wsServer.CloseStatus.HasValue)
                            {
                                clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);
                                continue;
                            }

                            looping = false;
                        }

                        await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted);
                    }
                    catch
                    {
                        try
                        {
                            var closeStatus  = clientResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = clientResult?.CloseStatusDescription ?? string.Empty;

                            await wsServer.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Above, we have created a bridge between the local and remote websocket. Wait for both
                // associated tasks to complete.
                await Task.WhenAll(serverTask, clientTask);
            }
            catch (Exception wshe)
            {
                if (wshe is System.Net.WebSockets.WebSocketException)
                {
                    var cast = wshe as System.Net.WebSockets.WebSocketException;

                    Console.WriteLine(cast.WebSocketErrorCode);
                    if (cast.Data != null)
                    {
                        foreach (KeyValuePair <object, object> kvp in cast.Data)
                        {
                            Console.WriteLine("{0} ::: {1}", kvp.Key, kvp.Value);
                        }
                    }
                }
                LoggerProxy.Default.Error(wshe);
            }
            finally
            {
                if (wsClient != null)
                {
                    wsClient.Dispose();
                    wsClient = null;
                }

                if (wsServer != null)
                {
                    wsServer.Dispose();
                    wsServer = null;
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="WebSocketReceiveResult"/> class.
 /// </summary>
 /// <param name="results">The results.</param>
 public WebSocketReceiveResult(System.Net.WebSockets.WebSocketReceiveResult results)
 {
     _results = results;
 }
        private static async System.Threading.Tasks.Task Prototype201803072_1()
        {
            // todo We need exception handling here.

            {
                double dateTimeFrequencyToPhaseFrequencyRatio =
                    (double)System.TimeSpan.TicksPerSecond / (double)System.Diagnostics.Stopwatch.Frequency;
                long basePhase = System.Diagnostics.Stopwatch.GetTimestamp();
                long baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks;
                basePhase = System.Diagnostics.Stopwatch.GetTimestamp();
                baseUtcDateTimeInTicks = System.DateTime.UtcNow.Ticks;

                var clientWebSocket = new System.Net.WebSockets.ClientWebSocket();
                await
                clientWebSocket.ConnectAsync
                    (new System.Uri
                        (@"wss://testnet.bitmex.com/realtime"),
                    //(@"wss://bitmex.com/realtime"),
                    System.Threading.CancellationToken.None
                    );

                // todo ??? The caller really should do this if needed.
                // todo ??? But any method really should do this
                // todo ??? if after {await} it's not supposed to return to the synchronization context.
                //// todo Comment in other places where we don't call this.
                //.ConfigureAwait(false);

                if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    {
                        const string message       = @"GET/realtime";
                        string       nonceAsString = (++Nonce_).ToString();

                        // todo Use ASCII encoding everywhere.
                        byte[] signatureBytes =
                            hmacsha256
                                (System.Text.Encoding.UTF8.GetBytes(ApiKeySecret_),
                                System.Text.Encoding.UTF8.GetBytes(message + nonceAsString)
                                );

                        string           signatureString = ByteArrayToString(signatureBytes);
                        /*const*/ string requestString   =
                            "{" +
                            "\"op\":\"authKey\"," +
                            "\"args\":[\"" + ApiKeyId_ + "\"," + nonceAsString + ",\"" + signatureString + "\"]" +
                            "}";
                        byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString);
                        await clientWebSocket.SendAsync
                            (new System.ArraySegment <byte>(requestBytes),
                            System.Net.WebSockets.WebSocketMessageType.Text,
                            true,
                            System.Threading.CancellationToken.None
                            );
                    }

                    if (clientWebSocket.State == System.Net.WebSockets.WebSocketState.Open)
                    {
                        {
                            const string subscriptionTopicName =
                                //@"quote:XBTUSD";
                                //@"trade:XBTUSD";
                                //@"orderBookL2:XBTUSD";
                                //@"instrument:XBTUSD";
                                //@"instrument";
                                //@"liquidation";
                                //@"quoteBin1m:XBTUSD";
                                @"order";

                            const string requestString =
                                "{" +
                                "\"op\":\"subscribe\"," +
                                "\"args\":[\"" + subscriptionTopicName + "\"]" +
                                "}";
                            byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(requestString);
                            await clientWebSocket.SendAsync
                                (new System.ArraySegment <byte>(requestBytes),

                                // todo ??? For GDAX binary didn't work, right?
                                System.Net.WebSockets.WebSocketMessageType.Text,
                                //System.Net.WebSockets.WebSocketMessageType.Binary,

                                true,
                                System.Threading.CancellationToken.None
                                );
                        }

                        // todo For GDAX this really doesn't need to be more than 16K, right?
                        var receiveBuffer = new System.ArraySegment <byte>(new byte[33 * 1024]);

                        for (bool isMessageBegin = true; ;)
                        {
                            if (clientWebSocket.State != System.Net.WebSockets.WebSocketState.Open)
                            {
                                System.Console.WriteLine(@"201802085");
                                break;
                            }
                            else
                            {
                            }

                            System.Net.WebSockets.WebSocketReceiveResult webSocketReceiveResult =
                                await clientWebSocket.ReceiveAsync(receiveBuffer, System.Threading.CancellationToken.None);

                            // todo Is this correct?
                            // todo Are these conditions equivalent?
                            if (webSocketReceiveResult.CloseStatus.HasValue || webSocketReceiveResult.Count <= 0)
                            {
                                System.Console.WriteLine(@"201802086");
                                break;
                            }
                            else
                            {
                            }

                            if (isMessageBegin)
                            {
                                isMessageBegin = false;
                                System.Console.WriteLine(',');
                                //System.Console.WriteLine();
                                long currentUtcDateTimeInTicks =
                                    (long)((double)(ulong)(System.Diagnostics.Stopwatch.GetTimestamp() - basePhase) * dateTimeFrequencyToPhaseFrequencyRatio + 0.5) +
                                    baseUtcDateTimeInTicks;
                                System.Console.Write
                                    ((new System.DateTime(currentUtcDateTimeInTicks)).ToString(@"o", System.Globalization.DateTimeFormatInfo.InvariantInfo));
                            }
                            else
                            {
                            }

                            // todo Preserve decoding state between decoding chunks.
                            string string1 =
                                System.Text.Encoding.ASCII.GetString(receiveBuffer.Array, 0, webSocketReceiveResult.Count);

                            System.Console.Write(string1);

                            if (webSocketReceiveResult.MessageType == System.Net.WebSockets.WebSocketMessageType.Close)
                            {
                                System.Console.WriteLine(@"201802087");
                                break;
                            }
                            else
                            {
                            }

                            if (webSocketReceiveResult.EndOfMessage)
                            {
                                isMessageBegin = true;
                                //break;
                            }
                            else
                            {
                            }
                        }
                    }
                    else
                    {
                        System.Console.WriteLine(@"201802088");
                    }
                }
                else
                {
                    System.Console.WriteLine(@"201804021");
                }

                // todo ??? WebSocketState >= CloseSent

                clientWebSocket.Dispose();
            }

            StaticBool1_ = true;
        }
Beispiel #13
0
 public MessageEventArgs(byte[] raw, System.Net.WebSockets.WebSocketReceiveResult result)
 {
     Result = result;
     Data   = raw;
 }
        /// <summary>
        /// Invoked when this handler is determined to be the best suited to handle the supplied connection.
        /// </summary>
        /// <param name="context">
        /// The HTTP context.
        /// </param>
        /// <returns>
        /// The handling task.
        /// </returns>
        public override async Task Handle(HttpContext context)
        {
            ClientWebSocket wsServer = null;

            System.Net.WebSockets.WebSocket wsClient = null;

            DiagnosticsWebSession diagSession = new DiagnosticsWebSession();

            try
            {
                // First we need the URL for this connection, since it's been requested to be upgraded to
                // a websocket.
                var fullUrl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request);

                // Need to replate the scheme with appropriate websocket scheme.
                if (fullUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
                {
                    fullUrl = "ws://" + fullUrl.Substring(7);
                }
                else if (fullUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                {
                    fullUrl = "wss://" + fullUrl.Substring(8);
                }

                diagSession.ClientRequestUri = fullUrl;

                // Next we need to try and parse the URL as a URI, because the websocket client requires
                // this for connecting upstream.

                if (!Uri.TryCreate(fullUrl, UriKind.RelativeOrAbsolute, out Uri wsUri))
                {
                    LoggerProxy.Default.Error("Failed to parse websocket URI.");
                    return;
                }

                // Create the websocket that's going to connect to the remote server.
                wsServer = new ClientWebSocket();
                wsServer.Options.Cookies = new System.Net.CookieContainer();
                wsServer.Options.SetBuffer((int)ushort.MaxValue * 16, (int)ushort.MaxValue * 16);

                foreach (var cookie in context.Request.Cookies)
                {
                    try
                    {
                        wsServer.Options.Cookies.Add(new Uri(fullUrl, UriKind.Absolute), new System.Net.Cookie(cookie.Key, System.Net.WebUtility.UrlEncode(cookie.Value)));
                    }
                    catch (Exception e)
                    {
                        LoggerProxy.Default.Error("Error while attempting to add websocket cookie.");
                        LoggerProxy.Default.Error(e);
                    }
                }

                if (context.Connection.ClientCertificate != null)
                {
                    wsServer.Options.ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection(new[] { context.Connection.ClientCertificate.ToV2Certificate() });
                }

                if (Collector.IsDiagnosticsEnabled)
                {
                    var diagHeaderBuilder = new StringBuilder();
                    foreach (var hdr in context.Request.Headers)
                    {
                        diagHeaderBuilder.AppendFormat($"{hdr.Key}: {hdr.Value.ToString()}\r\n");
                    }

                    diagSession.ClientRequestHeaders = diagHeaderBuilder.ToString();
                }

                var reqHeaderBuilder = new StringBuilder();
                foreach (var hdr in context.Request.Headers)
                {
                    if (!ForbiddenWsHeaders.IsForbidden(hdr.Key))
                    {
                        reqHeaderBuilder.AppendFormat("{0}: {1}\r\n", hdr.Key, hdr.Value.ToString());

                        try
                        {
                            wsServer.Options.SetRequestHeader(hdr.Key, hdr.Value.ToString());
                        }
                        catch (Exception hdrException)
                        {
                            LoggerProxy.Default.Error(hdrException);
                        }
                    }
                }

                reqHeaderBuilder.Append("\r\n");

                diagSession.ServerRequestHeaders = reqHeaderBuilder.ToString();

                // Connect the server websocket to the upstream, remote webserver.
                await wsServer.ConnectAsync(wsUri, context.RequestAborted);

                // Create, via acceptor, the client websocket. This is the local machine's websocket.
                wsClient = await context.WebSockets.AcceptWebSocketAsync(wsServer.SubProtocol ?? null);

                var msgNfo = new HttpMessageInfo
                {
                    Url             = wsUri,
                    IsEncrypted     = context.Request.IsHttps,
                    Headers         = context.Request.Headers.ToNameValueCollection(),
                    MessageProtocol = MessageProtocol.WebSocket,
                    MessageType     = MessageType.Request,
                    RemoteAddress   = context.Connection.RemoteIpAddress,
                    RemotePort      = (ushort)context.Connection.RemotePort,
                    LocalAddress    = context.Connection.LocalIpAddress,
                    LocalPort       = (ushort)context.Connection.LocalPort
                };

                _newMessageCb?.Invoke(msgNfo);

                switch (msgNfo.ProxyNextAction)
                {
                case ProxyNextAction.DropConnection:
                {
                    await wsClient.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);

                    return;
                }
                }

                // Spawn an async task that will poll the remote server for data in a loop, and then
                // write any data it gets to the client websocket.
                var serverTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult serverStatus = null;
                    var serverBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);

                        while (looping && !serverStatus.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            await wsClient.SendAsync(new ArraySegment <byte>(serverBuffer, 0, serverStatus.Count), serverStatus.MessageType, serverStatus.EndOfMessage, context.RequestAborted);

                            if (!wsClient.CloseStatus.HasValue)
                            {
                                serverStatus = await wsServer.ReceiveAsync(new ArraySegment <byte>(serverBuffer), context.RequestAborted);
                                continue;
                            }

                            looping = false;
                        }

                        await wsClient.CloseAsync(serverStatus.CloseStatus.Value, serverStatus.CloseStatusDescription, context.RequestAborted);
                    }
                    catch
                    {
                        try
                        {
                            var closeStatus  = serverStatus?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = serverStatus?.CloseStatusDescription ?? string.Empty;

                            await wsClient.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Spawn an async task that will poll the local client websocket, in a loop, and then
                // write any data it gets to the remote server websocket.
                var clientTask = Task.Run(async() =>
                {
                    System.Net.WebSockets.WebSocketReceiveResult clientResult = null;
                    var clientBuffer = new byte[1024 * 4];
                    try
                    {
                        bool looping = true;

                        clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);

                        while (looping && !clientResult.CloseStatus.HasValue && !context.RequestAborted.IsCancellationRequested)
                        {
                            await wsServer.SendAsync(new ArraySegment <byte>(clientBuffer, 0, clientResult.Count), clientResult.MessageType, clientResult.EndOfMessage, context.RequestAborted);

                            if (!wsServer.CloseStatus.HasValue)
                            {
                                clientResult = await wsClient.ReceiveAsync(new ArraySegment <byte>(clientBuffer), context.RequestAborted);
                                continue;
                            }

                            looping = false;
                        }

                        await wsServer.CloseAsync(clientResult.CloseStatus.Value, clientResult.CloseStatusDescription, context.RequestAborted);
                    }
                    catch
                    {
                        try
                        {
                            var closeStatus  = clientResult?.CloseStatus ?? System.Net.WebSockets.WebSocketCloseStatus.NormalClosure;
                            var closeMessage = clientResult?.CloseStatusDescription ?? string.Empty;

                            await wsServer.CloseAsync(closeStatus, closeMessage, context.RequestAborted);
                        }
                        catch { }
                    }
                });

                // Above, we have created a bridge between the local and remote websocket. Wait for both
                // associated tasks to complete.
                await Task.WhenAll(serverTask, clientTask);
            }
            catch (Exception wshe)
            {
                LoggerProxy.Default.Error(wshe);
            }
            finally
            {
                Collector.ReportSession(diagSession);

                if (wsClient != null)
                {
                    wsClient.Dispose();
                    wsClient = null;
                }

                if (wsServer != null)
                {
                    wsServer.Dispose();
                    wsServer = null;
                }
            }
        }