public async Task Close()
        {
            string          socket_id = browserSocket.GetHashCode() + this.Path;
            ProxyConnection tmp       = null;

            if (registered_sockets.ContainsKey(socket_id))
            {
                registered_sockets.TryRemove(socket_id, out tmp);
            }

            webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
            webSocket.Dispose();
        }
        public static void appServer_NewMessageReceived(WebSocket session, string message_string, string path, List <KeyValuePair <string, string> > headers)
        {
            try
            {
                string skey = manager == null ? null : manager.GetId(session);
                if (!string.IsNullOrWhiteSpace(message_string))
                {
                    DateTime t1 = DateTime.Now;

                    QuantApp.Kernel.RTDMessage message = null;

                    if (path.StartsWith("/lab/"))
                    {
                        var sessionID = session.GetHashCode() + path;
                        if (RTDSocketMiddleware._proxies.ContainsKey(sessionID))
                        {
                            var _client = RTDSocketMiddleware._proxies[sessionID];
                            _client.Send(message_string);
                        }
                        else
                        {
                            Console.WriteLine("Socket Not Found(" + path + "): " + message_string);
                        }
                    }

                    else
                    {
                        try
                        {
                            message = JsonConvert.DeserializeObject <QuantApp.Kernel.RTDMessage>(message_string);
                        }
                        catch {}

                        if (message != null)
                        {
                            if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.Subscribe)
                            {
                                try
                                {
                                    string contract = message.Content.ToString();

                                    if (contract.StartsWith("$"))
                                    {
                                        contract = contract.Substring(1, contract.Length - 1);
                                        if (!traders.ContainsKey(contract))
                                        {
                                            traders.TryAdd(contract, skey);
                                            Send(session, message_string);
                                        }
                                    }



                                    if (!subscriptions.ContainsKey(contract))
                                    {
                                        subscriptions.TryAdd(contract, new ConcurrentDictionary <string, WebSocket>());
                                    }

                                    if (!subscriptions[contract].ContainsKey(skey))
                                    {
                                        subscriptions[contract].TryAdd(skey, session);
                                    }

                                    // Console.WriteLine("Subscribed: " + skey + " -- " + contract);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("Subsribe Exception: " + e + " " + skey);
                                }
                            }
                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.RegisterWorkspace)
                            {
                                try
                                {
                                    string workspace = message.Content.ToString();

                                    Program.AddServicedWorkSpaces(workspace);

                                    if (!registered_id_workspaces.ContainsKey(skey))
                                    {
                                        registered_id_workspaces.TryAdd(skey, workspace);
                                    }

                                    if (!registered_workspaces_id.ContainsKey(workspace))
                                    {
                                        registered_workspaces_id.TryAdd(workspace, skey);
                                    }

                                    Console.WriteLine("Register: " + skey + " -- " + workspace);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("Register Exception: " + e + " " + skey);
                                }
                            }

                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.SaveM)
                            {
                                try
                                {
                                    string mid = message.Content.ToString();

                                    M m = M.Base(mid);
                                    m.Save();
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("SaveM Exception: " + e + " " + skey);
                                }
                            }
                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.PING)
                            {
                                try
                                {
                                    DateTime stamp = (DateTime)message.Content;

                                    var response = JsonConvert.SerializeObject(new QuantApp.Kernel.RTDMessage()
                                    {
                                        Type = QuantApp.Kernel.RTDMessage.MessageType.PING, Content = DateTime.Now
                                    });
                                    Send(session, response);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("MarketData Exception: " + e + " " + skey);
                                }
                            }
                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.UpdateQueue)
                            {
                                QuantApp.Kernel.QueueMessage qm = JsonConvert.DeserializeObject <QuantApp.Kernel.QueueMessage>(message.Content.ToString());

                                QuantApp.Kernel.RTDEngine.UpdateQueue(qm);

                                Share(session, qm.TopicID, message_string);
                            }
                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.CRUD)
                            {
                                QuantApp.Kernel.RTDMessage.CRUDMessage qm = JsonConvert.DeserializeObject <QuantApp.Kernel.RTDMessage.CRUDMessage>(message.Content.ToString());

                                try
                                {
                                    var type = Type.GetType(qm.ValueType);
                                    if (type == null)
                                    {
                                        Assembly assembly = QuantApp.Kernel.M._systemAssemblies.ContainsKey(qm.ValueType) ? QuantApp.Kernel.M._systemAssemblies[qm.ValueType] : (QuantApp.Kernel.M._compiledAssemblies.ContainsKey(qm.ValueType) ? QuantApp.Kernel.M._compiledAssemblies[qm.ValueType] : System.Reflection.Assembly.Load(qm.ValueAssembly));
                                        type = assembly.GetType(QuantApp.Kernel.M._systemAssemblyNames.ContainsKey(qm.ValueType) ? QuantApp.Kernel.M._systemAssemblyNames[qm.ValueType] : (QuantApp.Kernel.M._compiledAssemblyNames.ContainsKey(qm.ValueType) ? QuantApp.Kernel.M._compiledAssemblyNames[qm.ValueType] : qm.ValueType));
                                    }

                                    string filtered_string = qm.Value.ToString().Replace((char)27, '"').Replace((char)26, '\'');
                                    if (filtered_string.StartsWith("\"") && filtered_string.EndsWith("\""))
                                    {
                                        filtered_string = filtered_string.Substring(1, filtered_string.Length - 2).Replace("\\\"", "\"");
                                    }

                                    if (type == typeof(string) || qm.ValueType == null || type == typeof(Nullable))
                                    {
                                        qm.Value = filtered_string;
                                    }

                                    else if (type != null)
                                    {
                                        qm.Value = JsonConvert.DeserializeObject(filtered_string, type);
                                    }
                                }
                                catch {}

                                if (qm.Class == QuantApp.Kernel.M.CRUDClass)
                                {
                                    QuantApp.Kernel.M.Base(qm.TopicID).Process(qm);
                                }

                                Share(session, qm.TopicID, message_string);
                            }

                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.ProxyOpen)
                            {
                                var pd     = JsonConvert.DeserializeObject <HttpProxyRequest>(message.Content.ToString());
                                var client = ProxyConnection.Client(session, pd.Url);
                                client.Connect(pd.Content, pd.Headers);
                            }
                            else if (message.Type == QuantApp.Kernel.RTDMessage.MessageType.ProxyContent)
                            {
                                var pd = JsonConvert.DeserializeObject <HttpProxyRequest>(message.Content.ToString());

                                var sessionId = session.GetHashCode() + pd.Url;
                                if (RTDSocketMiddleware._proxies.ContainsKey(sessionId))
                                {
                                    var client = RTDSocketMiddleware._proxies[sessionId];
                                    client.Send(pd.Content);
                                }
                                else
                                {
                                    var client = ProxyConnection.Client(session, pd.Url);
                                    client.Send(pd.Content);
                                }
                            }

                            else if (RTDMessageFunction != null)
                            {
                                var mess = RTDMessageFunction(message_string);
                                if (mess != null)
                                {
                                    Share(session, mess.Item1, mess.Item2);
                                }
                            }
                        }

                        else
                        {
                            Console.WriteLine("UNKNOWN(" + path + "): " + message_string);
                        }
                    }

                    counter++;
                }
                else
                {
                    Console.WriteLine("--------------EMPTY STRING: " + path);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Server Receive Message Exception: " + e);
            }
        }
        public async Task Invoke(HttpContext context)
        {
            try
            {
                if (!context.WebSockets.IsWebSocketRequest)
                {
                    try
                    {
                        await _next.Invoke(context);
                    }
                    catch {}
                    return;
                }

                QuantApp.Kernel.User quser = null;

                string key = context.Request.Cookies["coflows"];
                if (key != null)
                {
                    quser = QuantApp.Kernel.User.FindUserBySecret(key);

                    if (quser == null)
                    {
                        await _next.Invoke(context);

                        return;
                    }
                }
                else
                {
                    // Console.WriteLine("WEBSOCKET NOT AUTHENTICATED");
                    await _next.Invoke(context);

                    return;
                }



                var queryString = context.Request.QueryString;
                var path        = context.Request.Path.ToString() + queryString;


                var headers = new List <KeyValuePair <string, string> >();

                foreach (var head in context.Request.Headers)
                {
                    foreach (var val in head.Value)
                    {
                        try
                        {
                            headers.Add(new KeyValuePair <string, string>(head.Key, val.Replace("%7C", "|")));
                        }
                        catch {}
                    }
                }

                var socket = await context.WebSockets.AcceptWebSocketAsync();

                var id      = _socketManager.AddSocket(socket);
                var address = context.Connection.RemoteIpAddress;

                if (path.StartsWith("/lab/"))
                {
                    var wid = path.Replace("/lab/", "");
                    wid = wid.Substring(0, wid.IndexOf("/"));

                    var client = ProxyConnection.Client(socket, path);
                    client.Connect("ws://localhost:8888", headers);

                    var _socket = client.ClientWebSocket;
                    _proxies.TryAdd(socket.GetHashCode() + path, client);
                }


                if (WebSocketListner.registered_address.ContainsKey(id))
                {
                    WebSocketListner.registered_address[id] = address;
                }
                else
                {
                    WebSocketListner.registered_address.TryAdd(id, address);
                }

                if (WebSocketListner.registered_sockets.ContainsKey(id))
                {
                    WebSocketListner.registered_sockets[id] = socket;
                }
                else
                {
                    WebSocketListner.registered_sockets.TryAdd(id, socket);
                }

                await Receive(socket, async (result, length, buffer) =>
                {
                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await _socketManager.RemoveSocket(id);
                        return;
                    }
                    else if (result.MessageType == WebSocketMessageType.Text)
                    {
                        string userMessage = Encoding.UTF8.GetString(buffer, 0, length);
                        WebSocketListner.appServer_NewMessageReceived(socket, userMessage, path, headers);
                        return;
                    }
                    else
                    {
                        Console.WriteLine("REC BIN1: " + result.MessageType);
                    }
                });
            }
            catch (Exception e)
            {
                Console.WriteLine("Invoke " + e);
                Console.WriteLine(e.StackTrace);
            }
        }