예제 #1
0
파일: Pubnub.cs 프로젝트: doxxon/pubnub-api
        /**
          * _subscribe - Private Interface
          *
          * @param Dictionary<string, object> args
          *  args is channel name and Procedure function callback and timetoken
          *
          */
        private void _subscribe(Dictionary<string, object> args)
        {
            Procedure callback = null, connect_cb, disconnect_cb, reconnect_cb, error_cb;
            clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY);

            object timetoken = args["timestamp"];
            string channel = args["channel"].ToString();
            // Validate Arguments
            if (args["callback"] != null)
            {
                callback = (Procedure)args["callback"];
            }
            else
            {
                Console.WriteLine("Invalid Callback.");
            }
            if(args.ContainsKey("connect_cb") && args["connect_cb"] != null)
                connect_cb = (Procedure)args["connect_cb"];
            else
                connect_cb = new Procedure(doNothing);
            if (args.ContainsKey("disconnect_cb") && args["disconnect_cb"] != null)
                disconnect_cb = (Procedure)args["disconnect_cb"];
            else
                disconnect_cb = new Procedure(doNothing);
            if (args.ContainsKey("reconnect_cb") && args["reconnect_cb"] != null)
                reconnect_cb = (Procedure)args["reconnect_cb"];
            else
                reconnect_cb = new Procedure(doNothing);
            if (args.ContainsKey("error_cb") && args["error_cb"] != null)
                error_cb = (Procedure)args["error_cb"];
            else
                error_cb = (Procedure)args["callback"];
            if (channel == null || channel =="")
            {
                error_cb("Invalid Channel.");
                return;
            }
            // Ensure Single Connection
            if (subscriptions != null && subscriptions.Count > 0)
            {
                bool channel_exist = false;
                foreach (Channel_status cs in subscriptions)
                {
                    if (cs.channel == channel)
                    {
                        channel_exist = true;
                        break;
                    }
                }
                if (!channel_exist)
                {
                    Channel_status cs = new Channel_status();
                    cs.channel = channel;
                    cs.connected = true;
                    subscriptions.Add(cs);
                }
                else
                {
                    error_cb("Already Connected");
                    return;
                }
            }
            else
            {
                // New Channel
                Channel_status cs = new Channel_status();
                cs.channel = channel;
                cs.connected = true;
                subscriptions = new List<Channel_status>();
                subscriptions.Add(cs);
            }

            bool is_reconnected = false;
            //  Begin Recusive Subscribe
            while (true)
            {

                //  Begin Recursive Subscribe
                try
                {
                    // Build URL
                    List<string> url = new List<string>();
                    url.Add("subscribe");
                    url.Add(this.SUBSCRIBE_KEY);
                    url.Add(channel);
                    url.Add("0");
                    url.Add(timetoken.ToString());

                    // Stop Connection?
                    bool is_disconnect = false;
                    foreach (Channel_status cs in subscriptions)
                    {
                        if (cs.channel == channel)
                        {
                            if (!cs.connected)
                            {
                                disconnect_cb("Disconnected to channel : " + channel);
                                is_disconnect = true;
                                break;
                            }
                        }
                    }
                    if (is_disconnect)
                        return;

                    // Wait for Message
                    List<object> response = _request(url);

                    // Stop Connection?
                    foreach (Channel_status cs in subscriptions)
                    {
                        if (cs.channel == channel)
                        {
                            if (!cs.connected)
                            {
                                disconnect_cb("Disconnected to channel : " + channel);
                                is_disconnect = true;
                                break;
                            }
                        }
                    }
                    if (is_disconnect)
                        return;
                    // Problem?
                    if (response == null || response[1].ToString() == "0")
                    {

                        for (int i = 0; i < subscriptions.Count(); i++)
                        {
                            Channel_status cs = subscriptions[i];
                            if (cs.channel == channel)
                            {
                                subscriptions.RemoveAt(i);
                                disconnect_cb("Disconnected to channel : " + channel);
                            }
                        }

                        // Ensure Connected (Call Time Function)
                        while (true)
                        {
                            string time_token = Time().ToString();
                            if (time_token == "0")
                            {
                                // Reconnect Callback
                                reconnect_cb("Reconnecting to channel : " + channel);
                                Thread.Sleep(5000);
                            }
                            else
                            {
                                is_reconnected = true;
                                break;
                            }
                        }
                        if (is_reconnected)
                        {
                            break;
                        }
                    }
                    else
                    {
                        foreach (Channel_status cs in subscriptions)
                        {
                            if (cs.channel == channel)
                            {
                                // Connect Callback
                                if (!cs.first)
                                {
                                    cs.first = true;
                                    connect_cb("Connected to channel : " + channel);
                                    break;
                                }
                            }
                        }
                    }

                    // Update TimeToken
                    if (response[1].ToString().Length > 0)
                        timetoken = (object)response[1];

                    // Run user Callback and Reconnect if user permits.
                    object message = "";
                    JArray val = (JArray)response[0];
                    for (int i = 0; i < val.Count; i++)
                    {
                        if (this.CIPHER_KEY.Length > 0)
                        {
                            if (val[i].Type == JTokenType.String)
                            {
                                message = pc.decrypt((string)val[i]);
                            }
                            else if (val[i].Type == JTokenType.Object)
                            {
                                message = pc.decrypt((JObject)val[i]);
                            }
                            else if (val[i].Type == JTokenType.Array)
                            {
                                message = pc.decrypt((JArray)val[i]);
                            }
                        }
                        else
                        {
                            message = val[i];
                        }

                        if (!callback(message)) return;
                    }
                }
                catch
                {
                    System.Threading.Thread.Sleep(1000);
                }
            }
            if (is_reconnected)
            {
                // Reconnect Callback
                args["channel"] = channel;
                args["callback"] = callback;
                args["timestamp"] = timetoken;
                this._subscribe(args);
            }
        }
예제 #2
0
        /**
         * _subscribe - Private Interface
         *
         * @param Dictionary<string, object> args
         *  args is channel name and Procedure function callback and timetoken
         *
         */
        private void _subscribe(Dictionary <string, object> args)
        {
            bool is_disconnect     = false;
            bool is_alreadyConnect = false;

            Procedure       callback = null, connect_cb, disconnect_cb, reconnect_cb, error_cb;
            clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY);

            object timetoken = args["timestamp"];
            string channel   = args["channel"].ToString();

            // Validate Arguments
            if (args["callback"] != null)
            {
                callback = (Procedure)args["callback"];
            }
            else
            {
                Console.WriteLine("Invalid Callback.");
            }
            if (args.ContainsKey("connect_cb") && args["connect_cb"] != null)
            {
                connect_cb = (Procedure)args["connect_cb"];
            }
            else
            {
                connect_cb = new Procedure(doNothing);
            }
            if (args.ContainsKey("disconnect_cb") && args["disconnect_cb"] != null)
            {
                disconnect_cb = (Procedure)args["disconnect_cb"];
            }
            else
            {
                disconnect_cb = new Procedure(doNothing);
            }
            if (args.ContainsKey("reconnect_cb") && args["reconnect_cb"] != null)
            {
                reconnect_cb = (Procedure)args["reconnect_cb"];
            }
            else
            {
                reconnect_cb = new Procedure(doNothing);
            }
            if (args.ContainsKey("error_cb") && args["error_cb"] != null)
            {
                error_cb = (Procedure)args["error_cb"];
            }
            else
            {
                error_cb = (Procedure)args["callback"];
            }
            if (channel == null || channel == "")
            {
                error_cb("Invalid Channel.");
                return;
            }
            // Ensure Single Connection
            if (subscriptions != null && subscriptions.Count > 0)
            {
                bool channel_exist = false;
                foreach (Channel_status cs in subscriptions)
                {
                    if (cs.channel == channel)
                    {
                        channel_exist = true;
                        if (!cs.connected)
                        {
                            cs.connected = true;
                        }
                        else
                        {
                            is_alreadyConnect = true;
                        }
                        break;
                    }
                }
                if (!channel_exist)
                {
                    Channel_status cs = new Channel_status();
                    cs.channel   = channel;
                    cs.connected = true;
                    subscriptions.Add(cs);
                }
                else if (is_alreadyConnect)
                {
                    error_cb("Already Connected");
                    return;
                }
            }
            else
            {
                // New Channel
                Channel_status cs = new Channel_status();
                cs.channel    = channel;
                cs.connected  = true;
                subscriptions = new List <Channel_status>();
                subscriptions.Add(cs);
            }

            bool is_reconnected = false;

            //  Begin Recusive Subscribe
            while (true)
            {
                //  Begin Recursive Subscribe
                try
                {
                    // Build URL
                    List <string> url = new List <string>();
                    url.Add("subscribe");
                    url.Add(this.SUBSCRIBE_KEY);
                    url.Add(channel);
                    url.Add("0");
                    url.Add(timetoken.ToString());

                    // Stop Connection?
                    is_disconnect = false;
                    foreach (Channel_status cs in subscriptions)
                    {
                        if (cs.channel == channel)
                        {
                            if (!cs.connected)
                            {
                                disconnect_cb("Disconnected to channel : " + channel);
                                is_disconnect = true;
                                break;
                            }
                        }
                    }
                    if (is_disconnect)
                    {
                        return;
                    }

                    // Wait for Message
                    List <object> response = _request(url);

                    // Stop Connection?
                    foreach (Channel_status cs in subscriptions)
                    {
                        if (cs.channel == channel)
                        {
                            if (!cs.connected)
                            {
                                disconnect_cb("Disconnected to channel : " + channel);
                                is_disconnect = true;
                                break;
                            }
                        }
                    }
                    if (is_disconnect)
                    {
                        return;
                    }
                    // Problem?
                    if (response == null || response[1].ToString() == "0")
                    {
                        for (int i = 0; i < subscriptions.Count(); i++)
                        {
                            Channel_status cs = subscriptions[i];
                            if (cs.channel == channel)
                            {
                                subscriptions.RemoveAt(i);
                                disconnect_cb("Disconnected to channel : " + channel);
                            }
                        }

                        // Ensure Connected (Call Time Function)
                        while (true)
                        {
                            string time_token = Time().ToString();
                            if (time_token == "0")
                            {
                                // Reconnect Callback
                                reconnect_cb("Reconnecting to channel : " + channel);
                                Thread.Sleep(5000);
                            }
                            else
                            {
                                is_reconnected = true;
                                break;
                            }
                        }
                        if (is_reconnected)
                        {
                            break;
                        }
                    }
                    else
                    {
                        foreach (Channel_status cs in subscriptions)
                        {
                            if (cs.channel == channel)
                            {
                                // Connect Callback
                                if (!cs.first)
                                {
                                    cs.first = true;
                                    connect_cb("Connected to channel : " + channel);
                                    break;
                                }
                            }
                        }
                    }

                    // Update TimeToken
                    if (response[1].ToString().Length > 0)
                    {
                        timetoken = (object)response[1];
                    }

                    // Run user Callback and Reconnect if user permits.
                    object message = "";
                    JArray val     = (JArray)response[0];
                    for (int i = 0; i < val.Count; i++)
                    {
                        if (this.CIPHER_KEY.Length > 0)
                        {
                            if (val[i].Type == JTokenType.String)
                            {
                                message = pc.decrypt((string)val[i]);
                            }
                            else if (val[i].Type == JTokenType.Object)
                            {
                                message = pc.decrypt((JObject)val[i]);
                            }
                            else if (val[i].Type == JTokenType.Array)
                            {
                                message = pc.decrypt((JArray)val[i]);
                            }
                        }
                        else
                        {
                            message = val[i];
                        }

                        if (!callback(message))
                        {
                            return;
                        }
                    }
                }
                catch
                {
                    System.Threading.Thread.Sleep(1000);
                }
            }
            if (is_reconnected)
            {
                // Reconnect Callback
                args["channel"]   = channel;
                args["callback"]  = callback;
                args["timestamp"] = timetoken;
                this._subscribe(args);
            }
        }