// Button รับ candidate จาก candidate text ที่เป็นรูปแบบ JSON พร้อมทั้ง peerID Link นั้น
        private void btn_Getcandidate_Click(object sender, RoutedEventArgs e)
        {
            Sender.ReceiveCandidate(Candidate.FromJson(TextBox_candidate.Text), peerID_link);

            //TextBox_sdp.AppendText("\n*************** Receiver candidate ***********\n");
            //TextBox_sdp.AppendText(TextBox_candidate.Text);
        }
        private void ReceiveOfferAnswerOrCandidate(NotifyReceiveArgs e)
        {
            var peerId    = e.NotifyingClient.ClientId.ToString();
            var peerState = e.NotifyingClient.BoundRecords;

            if (e.Tag == "offeranswer:" + SessionId)
            {
                Conference.ReceiveOfferAnswer(OfferAnswer.FromJson(e.DataJson), peerId, peerState);
            }
            else if (e.Tag == "candidate:" + SessionId)
            {
                Conference.ReceiveCandidate(Candidate.FromJson(e.DataJson), peerId);
            }
        }
        private Future <object> SubscribeToUserChannel()
        {
            Promise <object> promise = new Promise <object>();

            try
            {
                Client.Subscribe(new SubscribeArgs(UserChannel)
                {
                    OnSuccess = (o) =>
                    {
                        promise.Resolve(null);
                    },
                    OnFailure = (e) => {
                        promise.Reject(e.Exception);
                    },
                    OnReceive = (subscribeReceiveArgs) => {
                        try
                        {
                            string RemoteClientId = subscribeReceiveArgs.Client.ClientId.ToString();

                            Record Value;
                            if (subscribeReceiveArgs.PublishingClient.BoundRecords.TryGetValue(UserIdKey, out Value))
                            {
                                string RemoteUserId     = Serializer.DeserializeString(Value.ValueJson);
                                ConnectionInUserChannel = Connections.GetByExternalId(RemoteClientId);
                                if (subscribeReceiveArgs.Tag.Equals(CandidateTag))
                                {
                                    if (ConnectionInUserChannel == null)
                                    {
                                        ConnectionInUserChannel            = CreateConnectionAndWireOnLocalCandidate(new PeerClient(subscribeReceiveArgs.PublishingClient.ClientId.ToString(), subscribeReceiveArgs.PublishingClient.BoundRecords), RemoteUserId);
                                        ConnectionInUserChannel.ExternalId = RemoteClientId;
                                        Connections.Add(ConnectionInUserChannel);
                                    }

                                    Log.Info("Received candidate from remote peer.");
                                    ConnectionInUserChannel.AddRemoteCandidate(Candidate.FromJson(subscribeReceiveArgs.DataJson)).Fail((e) => {
                                        Log.Error("Could not process candidate from remote peer.", e);
                                    });
                                }
                                else if (subscribeReceiveArgs.Tag.Equals(OfferTag))
                                {
                                    Log.Info("Received offer from remote peer.");

                                    if (ConnectionInUserChannel == null)
                                    {
                                        ConnectionInUserChannel            = CreateConnectionAndWireOnLocalCandidate(new PeerClient(subscribeReceiveArgs.PublishingClient.ClientId.ToString(), subscribeReceiveArgs.PublishingClient.BoundRecords), RemoteUserId);
                                        ConnectionInUserChannel.ExternalId = RemoteClientId;
                                        Connections.Add(ConnectionInUserChannel);

                                        ConnectionInUserChannel.SetRemoteDescription(SessionDescription.FromJson(subscribeReceiveArgs.DataJson))
                                        .Then(new Function1 <SessionDescription, Future <SessionDescription> >((offer) =>
                                        {
                                            return(ConnectionInUserChannel.CreateAnswer());
                                        }))
                                        .Then(new Function1 <SessionDescription, Future <SessionDescription> >((answer) =>
                                        {
                                            return(ConnectionInUserChannel.SetLocalDescription(answer));
                                        }))
                                        .Then((answer) => {
                                            try
                                            {
                                                Client.Publish(new PublishArgs(RemoteUserChannel(RemoteUserId), answer.ToJson(), AnswerTag)
                                                {
                                                    OnSuccess = (a) => {
                                                        promise.Resolve(null);
                                                    },
                                                    OnFailure = (e) => {
                                                        promise.Reject(e.Exception);
                                                    }
                                                });
                                            }
                                            catch (Exception ex)
                                            {
                                                Log.Error(ex.Message);
                                            }
                                        })
                                        .Fail((e) => {
                                            Log.Error("Could not process offer from remote peer.", e);
                                        });
                                    }
                                }
                                else if (subscribeReceiveArgs.Tag.Equals(AnswerTag))
                                {
                                    if (ConnectionInUserChannel != null)
                                    {
                                        Log.Info("Received answer from remote peer");
                                        ConnectionInUserChannel.SetRemoteDescription(SessionDescription.FromJson(subscribeReceiveArgs.DataJson)).Fail((e) => {
                                            Log.Error("Could not process answer from remote peer.", e);
                                        });
                                    }
                                    else
                                    {
                                        Log.Error("Received answer, but connection does not exist!");
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e.Message);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
            return(promise);
        }