internal void DisconnectClient(WebSocketsClient wsclient)
        {
            if (wsclient.Socket.Connected)
            {
                OnClientDisconnect?.Invoke(this, new WebSocketsClientEventArgs(wsclient));
                clients.Remove(wsclient);

                try
                {
                    wsclient.Stream.Close();
                }
                catch (Exception e)
                {
                    OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
                }

                try
                {
                    wsclient.Stream.Dispose();
                }
                catch (Exception e)
                {
                    OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
                }

                try
                {
                    wsclient.Socket.Close();
                }
                catch (Exception e)
                {
                    OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
                }
            }
        }
        //Receive data from client's stream
        private void BeginReceive(IAsyncResult ar)
        {
            WebSocketsClient wsclient = (WebSocketsClient)ar.AsyncState;
            DataFrame        frame    = wsclient.EndReceive(ar);

            if (frame == null)
            {
                DisconnectClient(wsclient);
                return;
            }

            try
            {
                switch (frame.OpCode)
                {
                case OpCode.Text:
                    try
                    {
                        string payload = Encoding.UTF8.GetString(WebSocketsUtil.DecodePayload(frame));
                        OnMessage?.Invoke(this, new WebSocketsMessageEventArgs(wsclient, payload));
                    }
                    catch (Exception e)
                    {
                        OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
                    }
                    break;

                case OpCode.Binary:

                    break;

                case OpCode.Continue:

                    break;

                case OpCode.Ping:

                    break;

                case OpCode.Pong:

                    break;

                case OpCode.ConnectionClose:
                    DisconnectClient(wsclient);
                    break;

                default:

                    break;
                }
            }
            catch (Exception) { }

            wsclient.BeginReceive(BeginReceive, wsclient);
        }
        //Accept client's connection
        private void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = serverSocket.EndAccept(ar);

                WebSocketsClient wsclient = new WebSocketsClient(clientSocket, this);
                OnClientConnect?.Invoke(this, new WebSocketsClientEventArgs(wsclient));

                if (IsSecure)
                {
                    try
                    {
                        ((SslStream)wsclient.Stream).AuthenticateAsServer(Certificate, false, SslProtocols.Tls, true);
                    }
                    catch (Exception e)
                    {
                        OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
                    }
                }

                //Perform handshake
                if (Handshake.Accept(wsclient.Stream))
                {
                    clients.Add(wsclient);
                    wsclient.BeginReceive(BeginReceive, wsclient);
                    OnHandshakeComplete?.Invoke(this, new WebSocketsClientEventArgs(wsclient));
                }
                else
                {
                    DisconnectClient(wsclient);
                }
            }
            catch (Exception e)
            {
                OnError?.Invoke(this, new WebSocketsErrorEventArgs(e));
            }

            serverSocket.BeginAccept(AcceptCallback, null);
        }
 public WebSocketsMessageEventArgs(WebSocketsClient client, string message)
 {
     Client  = client;
     Message = message;
 }
 public WebSocketsClientEventArgs(WebSocketsClient client)
 {
     Client = client;
 }