public virtual void Remove(WebSocketHandler ws)
        {
            ws.OnClose -= Ws_OnClose;

            lock (subscribedWebsockets)
            {
                foreach (var ev in subscribedWebsockets.ToArray())
                {
                    ev.Value?.Remove(ws);
                    if (!ev.Value.Any())
                    {
                        subscribedWebsockets.Remove(ev.Key, out _);
                    }
                }
            }
            SubscritionsChange?.Invoke(this, subscribedWebsockets.Keys);
        }
        public virtual Dictionary <string, string> Unsubscribe(WebSocketHandler ws, string[] events)
        {
            Dictionary <string, string> result = new Dictionary <string, string>();

            lock (subscribedWebsockets)
            {
                foreach (var ev in events)
                {
                    subscribedWebsockets[ev]?.Remove(ws);
                    if (!subscribedWebsockets[ev].Any())
                    {
                        subscribedWebsockets.Remove(ev, out _);
                    }
                    result[ev] = "ok";
                }
            }

            SubscritionsChange?.Invoke(this, subscribedWebsockets.Keys);

            return(result);
        }
        public virtual Dictionary <string, string> Subscribe(WebSocketHandler ws, string[] events)
        {
            ws.OnClose -= Ws_OnClose;
            ws.OnClose += Ws_OnClose;
            Dictionary <string, string> result = new Dictionary <string, string>();

            lock (subscribedWebsockets)
            {
                foreach (var ev in events)
                {
                    if (!subscribedWebsockets.ContainsKey(ev))
                    {
                        subscribedWebsockets[ev] = new HashSet <WebSocketHandler>();
                    }

                    subscribedWebsockets[ev].Add(ws);
                    result[ev] = "ok";
                }
            }

            SubscritionsChange?.Invoke(this, subscribedWebsockets.Keys);

            return(result);
        }