예제 #1
0
        private void StartSubscription(PubnubSubscription subscription)
        {
            Task.Factory.StartNew(() =>
            {
                int failureCount = 0;

                // check if the subscription still exists in the dictionary
                // if not, then end this task, otherwise, repeat.
                using (var handle = new System.Threading.ManualResetEventSlim(false))
                {
                    while (_subscriptions.ContainsKey(subscription.Channel))
                    {
                        try
                        {
                            var url = PubnubRequest.BuildUrl(PubnubConfiguration.EnableSsl,
                                                             "subscribe",
                                                             PubnubConfiguration.SubscribeKey,
                                                             subscription.Channel,
                                                             "0",
                                                             subscription.TimeToken.ToString(CultureInfo.InvariantCulture));

                            var request = new PubnubRequest();
                            string json;
                            request.Execute(url, out json);

                            var result = JsonConvert.DeserializeObject<List<object>>(json);
            #if DEBUG
                            System.Diagnostics.Debug.WriteLine(json);
            #endif
                            if (result[0] is JArray && result[0].ToString() != "[]")
                            {
                                // loop through each message and fire individually
                                for (var i = 0; i < ((JArray)result[0]).Count; i++)
                                {
                                    var message = ((JArray)result[0])[i].ToString();
                                    if (MessageRecieved != null && !string.IsNullOrEmpty(message))
                                        try
                                        {
                                            MessageRecieved(null, new PubNubEventArgs
                                            {
                                                Channel = subscription.Channel,
                                                Message = message
                                            });
                                        }
                                        catch (Exception exp)
                                        {
                                            // adding this try catch because if we have multiple messages and one of
                                            // them encouters an unhandled exception it should not impact the others
                                            // or the subscription time token.
                                            System.Diagnostics.Debug.WriteLine("MessageRecievedException: " + exp.Message);
                                        }
                                }
                            }

                            // update the time token
                            PubnubSubscription retrievedSubscription;
                            if (_subscriptions.TryGetValue(subscription.Channel, out retrievedSubscription))
                                retrievedSubscription.TimeToken = Convert.ToInt64(result[1].ToString());

                            // reset the failure count
                            failureCount = 0;
                        }
                        catch (Exception exp)
                        {
                            System.Diagnostics.Debug.WriteLine("SubscriptionException: " + exp.Message);

                            failureCount++;
                            handle.Wait(GetWaitTimeForErrorCount(failureCount));

                            // rather than throwing the errors, we collect them for
                            // periodic analysis, the idea is to enhance this with error limits
                            // and a backoff strategy incase there is a problem with Pubnub
                            // or the local connection to pubnub
                            PubnubSubscription retrievedSubscription;
                            if (_subscriptions.TryGetValue(subscription.Channel, out retrievedSubscription))
                                retrievedSubscription.Errors.Add(exp);
                        }
                    }
                }

            });
        }
예제 #2
0
        /// <summary>
        /// Starts a looping subscription request which runs on it's own
        /// thread.
        /// </summary>
        /// <param name="channel"></param>
        /// <returns></returns>
        public bool Subscribe(string channel)
        {
            var subscription = new PubnubSubscription
            {
                Channel = channel,
                TimeToken = 0
            };

            // Add a new one
            if (!_subscriptions.TryAdd(channel, subscription))
                return false; //Subscription already exists

            StartSubscription(subscription);
            return true;
        }