none
Streaming subscription stops sending events RRS feed

  • Question

  • EWS Managed API 1.1, Exchange 2010SP1, C# in VS2010SP1

    I'm using streaming subs and after a while (indeterminate time and number of messages but on average 1 hour, ~50) notifications, the subscription stops raising events. Sometimes when this happens the EWS IIS becomes unresponsive and hangs. This is under no great load, I'm only monitoring 3 mailboxes in this test phase, and the load I'm testing with is around 20 messages per minute.

    This behaviour continues through reconnections until I restart the EWS IIS instance. Is this a known issue?

    Following is the code that constructs the connection and subscriptions:

            public EmailMonitor()
            {
                XmlConfigurator.Configure();
                if(_log == null)
                    _log = LogManager.GetLogger(GetType());
                _log.Info("Constructor START");
                _processedEmails = new List<ProcessedEmail>();
                _employeeLimitedList =
                    new List<string>((ConfigurationManager.AppSettings["EmployeeLimitedList"] ?? string.Empty).Split(','));
                _tracer = new MalaskraTracer(_log);
                ServicePointManager.ServerCertificateValidationCallback = OnValidationCallback;
                _service = GetService();
                _log.Info("Constructor COMPLETE");
            }
    
            private static ExchangeService GetService()
            {
                return new ExchangeService(ExchangeVersion.Exchange2010_SP1)
                           {
                               Url = new Uri(_exUrl),
                               UseDefaultCredentials = _exUsername == null || _exPassword == null,
                               ImpersonatedUserId = _malaskraImpersonatedUserId,
                               AcceptGzipEncoding = true,
                               PreferredCulture = CultureInfo.GetCultureInfo("IS"),
                               Timeout = 15000
                               /*
                               TraceEnabled = true,
                               TraceListener = _tracer,
                               TraceFlags = TraceFlags.DebugMessage
                               */
                           };
            }
    
            public void Start(int serviceTimeout = 10)
            {
                _log.Debug("Start() - Starting");
                _malaskraFolder = Folder.Bind(_service, WellKnownFolderName.Inbox);
                FolderSearch.GetUserMailFolders(_malaskraFolder, _folders);
    
                BuildSubscriptions();
                
                try
                {
                    _service.ImpersonatedUserId = _malaskraImpersonatedUserId;
                    _subscriptionConnection = new StreamingSubscriptionConnection(_service, serviceTimeout);
                    _subscriptionConnection.OnNotificationEvent += OnEvent;
                    _subscriptionConnection.OnSubscriptionError += OnError;
                    _subscriptionConnection.OnDisconnect += OnDisconnect;
                    foreach (SubscriptionInfo info in _subscriptionUserMap)
                    {
                        _subscriptionConnection.AddSubscription(info.Subscription);
                        _log.Debug("Added subscription " + info.Subscription.Id + " for " + info.UserEmail);
                    }
                    _subscriptionConnection.Open();
                }
                catch (ServiceResponseException ex)
                {
                    _log.Error("Error creating subscriptions", ex);
                    throw;
                }
                catch(Exception ex)
                {
                    _log.Error(ex.Message, ex);
                }
                /*
                _syncTimer = new Timer(60000);
                _syncTimer.Elapsed += SyncNow;
                _syncTimer.Start();
                 */
                _log.Debug("Start() - Finished");
            }
    
            private void BuildSubscriptions()
            {
                List<string> allEmployees;
                if (_employeeLimitedList.Count > 0)
                {
                    allEmployees =
                        (from emp in _mimisbrunnur.EmployeesVs
                         where _employeeLimitedList.Contains(emp.UserName)
                         select emp.Email).ToList();
                    _log.Debug("allEmployees " + string.Join(", ", allEmployees.ToArray()));
                }
                else
                {
                    allEmployees = (from emp in _mimisbrunnur.EmployeesVs select emp.Email).ToList();
                }
    
                _subscriptionUserMap.Add(new SubscriptionInfo(_service, MalaskraEmail));
    
                foreach (
                    string email in
                        allEmployees.Select(
                            empEmail => _emailDomain != null ? empEmail.Replace("vis.is", _emailDomain) : empEmail))
                {
                    try
                    {
                        _subscriptionUserMap.Add(new SubscriptionInfo(_service, email));
                        _log.Debug("Added sub for " + email);
                    }
                    catch (Exception ex)
                    {
                        _log.Warn(ex.Message, ex);
                    }
                }
            }
    
    

    As you might notice I've tested runs with a tracer attached but it doesn't seem to generate any messages when the event occurs. Neither are there any exceptions raised.


    For reference, here is the SubscriptionInfo class:

        internal class SubscriptionInfo
        {
            public SubscriptionInfo(ExchangeService service, string userEmail)
            {
                UserEmail = userEmail;
                ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, userEmail);
                service.ImpersonatedUserId = ImpersonatedUserId;
                InboxId = Folder.Bind(service, WellKnownFolderName.Inbox).Id;
                SentItemsId = Folder.Bind(service, WellKnownFolderName.SentItems).Id;
                OutboxId = Folder.Bind(service, WellKnownFolderName.Outbox).Id;
                Subscription = service.SubscribeToStreamingNotifications(new[] { InboxId, SentItemsId }, EventType.NewMail, EventType.Created, EventType.Moved);
            }
    
            public string UserEmail;
            public StreamingSubscription Subscription;
            public FolderId InboxId;
            public FolderId SentItemsId;
            public FolderId OutboxId;
            public ImpersonatedUserId ImpersonatedUserId;
            public string SyncState;
        }
    


    Friday, January 6, 2012 2:29 PM

All replies

  • Here is the event handling code:

            private void OnEvent(object sender, NotificationEventArgs args)
            {
                foreach (ItemEvent evt in args.Events.OfType<ItemEvent>())
                {
                    SubscriptionInfo info =
                        _subscriptionUserMap.First(s => s.Subscription == args.Subscription);
                    if (info.UserEmail != MalaskraEmail)
                    {
                        try
                        {
                            //var t = new Thread(CopyMailToMalaskra);
                            //t.Start(evt.ItemId);
                            CopyMailEvent(evt, info);
                        }
                        catch (ServiceResponseException ex)
                        {
                            _log.Error(ex.Message, ex);
                        }
                        catch (Exception ex)
                        {
                            _log.Error(ex.Message, ex);
                        }
                    }
                    else if(evt.EventType == EventType.Created)
                    {
                        try
                        {
                            //var t = new Thread(ProcessMailInMalaskra);
                            //t.Start(evt.ItemId);
                            SaveMailEvent(evt);
                        }
                        catch (ServiceResponseException ex)
                        {
                            _log.Error(ex.Message, ex);
                        }
                        catch (Exception ex)
                        {
                            _log.Error(ex.Message, ex);
                        }
                    }
                }
            }
    
    The sub methods (CopyMailEvent and SaveMailEvent) call EWS with some more logic, along with sending AMQP messages and more. I've tried branching them off into separate threads to no avail.

    Friday, January 6, 2012 2:36 PM
  • Im facing this same issue - did you ever figure it out?
    Tuesday, January 16, 2018 11:41 AM