public async Task WaitHandShake()
        {
            if (WebSocket.State == WebSocketState.Open)
            {
                // Wait for handshake
                var handshakeData = JObject.Parse(await Receive());
                if (handshakeData["receiverId"] == null ||
                    handshakeData["receiverId"].ToString() != "TMCS" ||
                    handshakeData["type"] == null ||
                    handshakeData["type"].ToString() != "Signal" ||
                    handshakeData["data"]["signal"] == null ||
                    handshakeData["data"]["signal"].ToString() != "HandShake"
                    )
                {
                    await SendTextAsync(await TMCSTest.JSONStringifyAsync(new
                    {
                        type       = "Signal",
                        senderId   = "TMCS",
                        receiverId = "[user]",
                        data       = new
                        {
                            signal = "Error",
                            data   = -100
                        }
                    }));

                    return;
                }
                await HandShake(handshakeData["data"]["data"]);

                // Wait for start signal
                var readyData = JObject.Parse(await Receive());
                if (readyData["receiverId"] == null ||
                    readyData["receiverId"].ToString() != "TMCS" ||
                    readyData["type"] == null ||
                    readyData["type"].ToString() != "Signal" ||
                    readyData["data"]["signal"] == null ||
                    readyData["data"]["signal"].ToString() != "Ready"
                    )
                {
                    await SendTextAsync(await TMCSTest.JSONStringifyAsync(new
                    {
                        type       = "Signal",
                        senderId   = "TMCS",
                        receiverId = "[user]",
                        data       = new
                        {
                            signal = "Error",
                            data   = -100
                        }
                    }));

                    return;
                }
            }
        }
        public async Task StartReceiev()
        {
            if (WebSocket != null)
            {
                if (this.Uid == null || this.Uid == "")
                {
                    await WaitHandShake();
                }
                var msgToSend = new TMCSTest.Message[] {
                    new TMCSTest.Message("SardineFish", Uid, TMCSTest.MessageType.Text, "Welcom to TMCS!"),
                    new TMCSTest.Message("SardineFish", Uid, TMCSTest.MessageType.Text, "TMCS is now developing."),
                    new TMCSTest.Message("SardineFish", Uid, TMCSTest.MessageType.Text, "It is just a demo now.")
                };

                await SendTextAsync(await TMCSTest.JSONStringifyAsync(msgToSend));

                while (WebSocket.State == WebSocketState.Open)
                {
                    try
                    {
                        var textData = await Receive();

                        JObject rcvObj   = JObject.Parse(textData);
                        var     receiver = rcvObj["receiverId"].ToString();
                        if (receiver == "TMCS")
                        {
                            var data = rcvObj["data"].ToString();
                            //var data = TMCSTest.RSADecrypt(Convert.FromBase64String(dataEnc), TMCSTest.PRIVATE_KEY);
                            //var dataText = Encoding.UTF8.GetString(data);
                            if (rcvObj["type"].ToString() == "Signal")
                            {
                                await HandleSignal(JObject.Parse(data));
                            }
                        }
                        else
                        {
                            await HandleMessage(rcvObj);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                        if (Uid != null && Uid != "")
                        {
                            TMCSTest.HandlerList.Remove(Uid);
                        }
                        return;
                    }
                }
            }
        }
        public async Task HandleMessage(JObject msgData)
        {
            var receiver = msgData["receiverId"].ToString();

            if (TMCSTest.HandlerList.ContainsKey(receiver))
            {
                var send = new object[] {
                    new {
                        type     = msgData["type"].ToString(),
                        senderId = Uid,
                        data     = msgData["data"].ToString()
                    }
                };

                var msgToSendJson = await TMCSTest.JSONStringifyAsync(send);

                await TMCSTest.HandlerList[receiver].SendTextAsync(msgToSendJson);
            }
            else
            {
                var sender = "";
                if (TMCSTest.rand.NextDouble() < 0.5)
                {
                    sender = receiver;
                }
                else
                {
                    sender = TMCSTest.RandomUid();
                }
                var send = new object[] {
                    new {
                        type     = msgData["type"].ToString(),
                        senderId = sender,
                        data     = msgData["data"].ToString()
                    }
                };

                var msgToSendJson = await TMCSTest.JSONStringifyAsync(send);
                await SendTextAsync(msgToSendJson);
            }
        }
        public async Task HandShake(JToken data)
        {
            var uid   = data["uid"].ToString();
            var token = data["token"].ToString();

            this.Uid   = uid;
            this.Token = token;
            await SendTextAsync(await TMCSTest.JSONStringifyAsync(new
            {
                type     = "Signal",
                senderId = "TMCS",
                data     = new
                {
                    signal = "HandShake",
                    data   = new
                    {
                        serverName = "TMCS-Test",
                        owner      = "MDZZ.studio",
                        version    = "0.1.0-alpha",
                        pubKey     = TMCSTest.PUBLIC_KEY
                    }
                }
            }));
        }