Search code examples
c#exchangewebservices

EWS streaming notifications not received


I have a windows service which subscribes to an Office365 email account and awaits new emails, when they arrive it processes their attachments, and all is well with the world.

But... for some reason, the applications stops receiving notifications after an undetermined amount of time.

I have handled the 'OnDisconnect' event and reestablish a connection as shown in the below code, but that doesnt seem to be fixing this issue. The windows service continues to run fine, and if I restart the service everything is good again, until is failed again.

This is the my class for running exchange:

 public class ExchangeConnection
    {
        static readonly ExchangeService Service = Exchange.Service.ConnectToService(UserDataFromConsole.GetUserData(), new TraceListener());
        public event EmailReceivedHandler OnEmailReceived;

        public ExchangeConnection()
        {
        }

        public void Open()
        {
            SetStreamingNotifications(Service);

            var signal = new AutoResetEvent(false);
            signal.WaitOne();
        }

        private void SetStreamingNotifications(ExchangeService service)
        {
            var streamingsubscription = service.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Inbox }, EventType.NewMail);

            var connection = new StreamingSubscriptionConnection(service, 30);

            connection.AddSubscription(streamingsubscription);
            connection.OnNotificationEvent += OnEvent;
            connection.OnSubscriptionError += OnError;
            connection.OnDisconnect += OnDisconnect;
            connection.Open();
        }

        public void MoveEmail(ItemId id, String folderName = "Archived Emails")
        {
            var rootFolder = Folder.Bind(Service, WellKnownFolderName.Inbox);

            var archivedFolder = rootFolder.FindFolders(new FolderView(100)).FirstOrDefault(x => x.DisplayName == folderName);

            if (archivedFolder == null)
            {
                archivedFolder = new Folder(Service) { DisplayName = folderName };
                archivedFolder.Save(WellKnownFolderName.Inbox);
            }

            Service.MoveItems(new List<ItemId> {id}, archivedFolder.Id);
        }

        #region events
        private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            //The connection is disconnected every 30minutes, and we are unable to override this,
            //so when we get disconnected we just need to reconnect again.
            var connection = (StreamingSubscriptionConnection)sender;

            connection.Open();
        }
        private void OnEvent(object sender, NotificationEventArgs args)
        {
            var subscription = args.Subscription;

            // Loop through all item-related events. 
            foreach (var notification in args.Events)
            {
                switch (notification.EventType)
                {
                    case EventType.NewMail:

                        if (notification is ItemEvent)
                        {
                            var email = Item.Bind(Service, new ItemId(((ItemEvent) notification).ItemId.UniqueId));
                            OnEmailReceived(new EmailReceivedArgs((EmailMessage)email));
                        }

                        break;
                }

            }
        }
        private void OnError(object sender, SubscriptionErrorEventArgs args)
        {
            var e = args.Exception;
            Logger.LogException(e,LogEventType.Error);
        }
        #endregion events

}

Any help would be great, thanks.

After improving the error logging I have found this exception occurring:

Exception: The specified subscription was not found.

Any ideas what is causing this?


Solution

  • With Office365 you need to make sure you deal with affinity see http://msdn.microsoft.com/en-us/library/office/dn458789(v=exchg.150).aspx . Adding those headers will ensure your requests will always routed to the correct servers.