public override void Send(string channel, string message)
        {
            #region Sanity Checks

            if (!IsConnected)
            {
                RaiseOnException(new OrtcException("Not connected"));
            }
            else if (String.IsNullOrEmpty(channel))
            {
                RaiseOnException(new OrtcException("Channel is null or empty"));
            }
            else if (!channel.OrtcIsValidInput())
            {
                RaiseOnException(new OrtcException("Channel has invalid characters"));
            }
            else if (String.IsNullOrEmpty(message))
            {
                RaiseOnException(new OrtcException("Message is null or empty"));
            }
            else
            #endregion
            {
                Task.RunOnMain(() =>
                {
                    IosOrtcClientFactory.SendMessage(_id, channel, message);
                });
            }
        }
        public override void Unsubscribe(string channel)
        {
            #region Sanity Checks

            bool sanityChecked = true;

            if (!IsConnected)
            {
                RaiseOnException(new OrtcException("Not connected"));
                sanityChecked = false;
            }
            else if (String.IsNullOrEmpty(channel))
            {
                RaiseOnException(new OrtcException("Channel is null or empty"));
                sanityChecked = false;
            }
            else if (!channel.OrtcIsValidInput())
            {
                RaiseOnException(new OrtcException("Channel has invalid characters"));
                sanityChecked = false;
            }
            else if (!_subscribedChannels.ContainsKey(channel))
            {
                RaiseOnException(new OrtcException(String.Format("Not subscribed to the channel {0}", channel)));
                sanityChecked = false;
            }
            else if (_subscribedChannels.ContainsKey(channel))
            {
                ChannelSubscription channelSubscription = null;
                _subscribedChannels.TryGetValue(channel, out channelSubscription);

                if (channelSubscription != null && !channelSubscription.IsSubscribed)
                {
                    RaiseOnException(new OrtcException(String.Format("Not subscribed to the channel {0}", channel)));
                    sanityChecked = false;
                }
            }
            else
            {
                byte[] channelBytes = Encoding.UTF8.GetBytes(channel);

                if (channelBytes.Length > MAX_CHANNEL_SIZE)
                {
                    RaiseOnException(new OrtcException(String.Format("Channel size exceeds the limit of {0} characters", MAX_CHANNEL_SIZE)));
                    sanityChecked = false;
                }
            }

            #endregion

            if (sanityChecked)
            {
                Task.RunOnMain(() =>
                {
                    IosOrtcClientFactory.Unsubscribe(_id, channel);
                });
            }
        }
        public override void Dispose()
        {
            IosOrtcClientFactory.DestroyClient(this);

            if (IsConnected)
            {
                Disconnect();
            }
        }
        public override void Connect(string appKey, string authToken)
        {
            #region Sanity Checks
            //if (Application.internetReachability == NetworkReachability.NotReachable)
            //{
            //    RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Internet not reachable"));
            //}
            //else
            if (IsConnected)
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Already connected"));
            }
            else if (_isConnecting)
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Already trying to connect"));
            }
            else if (String.IsNullOrEmpty(ClusterUrl) && String.IsNullOrEmpty(Url))
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "URL and Cluster URL are null or empty"));
            }
            else if (String.IsNullOrEmpty(appKey))
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Application Key is null or empty"));
            }
            else if (String.IsNullOrEmpty(authToken))
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Authentication ToKen is null or empty"));
            }
            else if (!IsCluster && !Url.OrtcIsValidUrl())
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Invalid URL"));
            }
            else if (IsCluster && !ClusterUrl.OrtcIsValidUrl())
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Invalid Cluster URL"));
            }
            else if (AnnouncementSubChannel != null && !AnnouncementSubChannel.OrtcIsValidInput())
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, "Announcement Subchannel has invalid characters"));
            }
            else if (!String.IsNullOrEmpty(ConnectionMetadata) && ConnectionMetadata.Length > MAX_CONNECTION_METADATA_SIZE)
            {
                RaiseOnException(new OrtcException(OrtcExceptionReason.InvalidArguments, String.Format("Connection metadata size exceeds the limit of {0} characters", MAX_CONNECTION_METADATA_SIZE)));
            }
            else

            #endregion

            {
                Task.RunOnMain(() =>
                {
                    IosOrtcClientFactory.Connect(_id, appKey, authToken);
                });
            }
        }
        public override void Disconnect()
        {
            _isConnecting = false;
            _subscribedChannels.Clear();

            if (!IsConnected)
            {
                RaiseOnException(new OrtcException("Not connected"));
            }
            else
            {
                Task.RunOnMain(() =>
                {
                    IosOrtcClientFactory.Disconnect(_id);
                });
            }
        }
        internal void RaiseOnConnected()
        {
            TaskManager.RunOnMainThread(() =>
            {
                SessionId = IosOrtcClientFactory.GetSessionId(_id);

                IsConnected = true;

                var ev = OnConnected;

                if (ev == null)
                {
                    return;
                }

                ev();
            });
        }
 public string GetSession()
 {
     return(IosOrtcClientFactory.GetSessionId(_id));
 }