private void AddBroadcastListener()
        {
            connection_.AddBroadcastCallbackHandler("connecttovpn", (JObject response) =>
            {
                //RouterVpnManagerLogLibrary.Log("Connection has been made to " + response["data"].ToString());
                ConnectToVpnResponse ctvr = response.ToObject <ConnectToVpnResponse>();
                ctvr.SetData();
                listener_?.ConnectedToVpn(ctvr);
            });

            connection_.AddBroadcastCallbackHandler("disconnectfrompvpn", (JObject response) =>
            {
                //RouterVpnManagerLogLibrary.Log("Disconnection has been made from " + response["data"].ToString());
                DisconnectFromVpnResponse dfvr = response.ToObject <DisconnectFromVpnResponse>();
                dfvr.SetData();
                listener_?.DisconnectedFromVpn(dfvr);
            });

            connection_.AddBroadcastCallbackHandler("broadcastlog", (JObject response) =>
            {
                BroadcastMessage bm = response.ToObject <BroadcastMessage>();
                bm.SetData();
                RouterVpnManagerLogLibrary.LogBroadcastMessage(bm.Message);
            });
        }
        public void Connect()
        {
            try
            {
                IPEndPoint ep = new IPEndPoint(IPAddress.Parse(Host), Port);
                client_.Connect(ep);


                requestProcessor_.Start();

                JObject obj = ControlledRequests.FormatMessage("request", "connection");
                obj["signature"] = Guid.NewGuid().ToString();
                byte[] bytes = Encoding.ASCII.GetBytes(obj.ToString());

                bool state = false;
                HasCallbackBeenRecieved callbackstate = AddCallback(obj, (JObject message) =>
                {
                    RouterVpnManagerLogLibrary.Log(message["data"].ToString());
                    state = true;
                });
                NetworkStream ns = client_.GetStream();
                ns.Write(bytes, 0, bytes.Length);
                callbackstate.Wait(CallbackTimeout);
                if (!state)
                {
                    throw new Exception("was not able to connect properly");
                }
            }
            catch (Exception e)
            {
                RouterVpnManagerLogLibrary.Log(e.ToString());
                throw e;
            }
        }
        public StatusResponse SaveConfig(string name)
        {
            dynamic d = new ExpandoObject();

            d.name = name;
            JObject        obj    = FormatMessage("request", "copycurrentconfig", d);
            StatusResponse status = false;

            connection_.SendJson(obj, (JObject response) =>
            {
                try
                {
                    StatusResponse rb = response.ToObject <StatusResponse>();
                    rb.SetData();
                    status = rb;
                }
                catch (Exception e)
                {
                    RouterVpnManagerLogLibrary.Log(e.ToString());
                    status = new StatusResponse {
                        Status = false, ExceptionMessage = e.ToString()
                    };
                }
            }).Wait(connection_.CallbackTimeout);

            return(status);
        }
        protected void ProcessResponses()
        {
            responseProcessTask_ = Task.Run(() =>
            {
                while (responseProcessListener_)
                {
                    try
                    {
                        JObject obj = responses_.Take();

                        if (obj["type"].ToString() == "broadcast")
                        {
                            if (broadcastCallbacksHandlers_.ContainsKey(obj["request"].ToString()))
                            {
                                broadcastCallbacksHandlers_.TryGetValue(obj["request"].ToString(), out var callback);
                                callback?.Invoke(obj);
                                Func <KeyValuePair <JObject, HasCallbackBeenRecieved>, bool> equalCheck = (KeyValuePair <JObject, HasCallbackBeenRecieved> x) =>
                                                                                                          x.Key["request"] != null && obj["request"] != null && x.Key["signature"] != null && obj["signature"] != null &&
                                                                                                          x.Key["request"].ToString() == obj["request"].ToString() && x.Key["signature"].ToString() == obj["signature"].ToString();

                                if (broadcastCallback_.Any(equalCheck))//this may not work properly
                                {
                                    JObject key = broadcastCallback_.First(equalCheck).Key;
                                    HasCallbackBeenRecieved response;
                                    if (broadcastCallback_.TryRemove(key, out response))
                                    {
                                        response.SignalEvent.Set();
                                    }
                                    else
                                    {
                                        RouterVpnManagerLogLibrary.Log("Error removing ");
                                    }
                                }
                            }
                        }
                        else if (obj["type"].ToString() == "response")
                        {
                            Func <KeyValuePair <JObject, Callback>, bool> equalCheck = (KeyValuePair <JObject, Callback> x) => x.Key["request"].ToString() == obj["request"].ToString() && x.Key["signature"].ToString() == obj["signature"].ToString();
                            if (privateCallbacks_.Any(equalCheck))
                            {
                                JObject key = privateCallbacks_.Where(equalCheck).First().Key;
                                Callback response;
                                if (privateCallbacks_.TryRemove(key, out response))
                                {
                                    response?.Invoke(obj);
                                }
                                else
                                {
                                    RouterVpnManagerLogLibrary.Log("Error removing ");
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        RouterVpnManagerLogLibrary.Log("Something Blew Up: " + ex.ToString());
                    }
                }
            });
        }
        public ConnectionStatusResponse CheckCurrentConnection()
        {
            JObject obj = FormatMessage("request", "checkconnectionstatus");
            ConnectionStatusResponse currentConnection = null;

            connection_.SendJson(obj, (JObject response) =>
            {
                try
                {
                    currentConnection = response.ToObject <ConnectionStatusResponse>();
                    currentConnection.SetData();
                }
                catch (Exception e)
                {
                    RouterVpnManagerLogLibrary.Log(e.ToString());
                }
            }).Wait(connection_.CallbackTimeout);
            return(currentConnection);
        }