user2897967
user2897967

Reputation: 337

EWS managed API streaming notification ...NewMail watcher using C# maildeleted event is not notified

.Net application which will subscribe to streaming notification. This application executes well, this subscription disconnected after 30 mints so I added the code to reconnect the connection .I tested the application by adding break point at the reconnect line and waited for some time before it established the connection again. During that time I created a few new emails and watched if console displays those events. It did not as connection was disconnected then I run the code again and I was able to see the events which were created during the time connection disconnected and connected. I need to know if this is the right way to make this process run continuously and track the events which occurred during the disconnect and reconnect of the application. also need to know why the below code is not notifying about delete mail event. kindly looking for help.

namespace NewMailNotification
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            //***********New**********************
            ExchangeService  mailbox = new ExchangeService(ExchangeVersion.Exchange2010_SP2); 
            string mailboxEmail = ConfigurationSettings.AppSettings["user-id"]; 
            WebCredentials wbcred = new WebCredentials(ConfigurationSettings.AppSettings["user"], ConfigurationSettings.AppSettings["PWD"]); 
            mailbox.Credentials = wbcred;
        //    mailbox.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxEmail);

            mailbox.AutodiscoverUrl(mailboxEmail, RedirectionUrlValidationCallback);
            mailbox.HttpHeaders.Add("X-AnchorMailBox", mailboxEmail);
            FolderId mb1Inbox = new FolderId(WellKnownFolderName.Inbox, mailboxEmail);
            SetStreamingNotification(mailbox, mb1Inbox);
            bool run = true;
            bool reconnect = false;
            while (run)
            {
                System.Threading.Thread.Sleep(100);
            }
        }

        internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            //The default for the validation callback is to reject the URL
            bool result=false;

            Uri redirectionUri=new Uri(redirectionUrl);
            if(redirectionUri.Scheme=="https")
            {
                result=true;
            }
            return result;
        }

        static void SetStreamingNotification(ExchangeService service,FolderId fldId)
        {
            StreamingSubscription streamingssubscription=service.SubscribeToStreamingNotifications(new FolderId[]{fldId},
                EventType.NewMail,
                EventType.Created,
                EventType.Deleted);

            StreamingSubscriptionConnection connection=new StreamingSubscriptionConnection(service,30);
            connection.AddSubscription(streamingssubscription);

            //Delagate event handlers
            connection.OnNotificationEvent+=new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
            connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(Connection_OnDisconnect);
            connection.OnSubscriptionError+=new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
            connection.Open();

        }

        static private void Connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
            if (!connection.IsOpen)             
            {
                //  Console.WriteLine("no connection");
                connection.Open();
            }
        }

        static void OnEvent(object sender,NotificationEventArgs args)
        {
            StreamingSubscription subscription=args.Subscription;
            if(subscription.Service.HttpHeaders.ContainsKey("X-AnchorMailBox"))
            {
                Console.WriteLine("event for nailbox"+subscription.Service.HttpHeaders["X-AnchorMailBox"]);
            }
            //loop through all the item-related events.
            foreach(NotificationEvent notification in args.Events)
            {
                switch(notification.EventType)
                {
                    case EventType.NewMail:
                        Console.WriteLine("\n----------------Mail Received-----");
                        break;
                    case EventType.Created:
                        Console.WriteLine("\n-------------Item or Folder deleted-------");
                        break;
                    case EventType.Deleted:
                        Console.WriteLine("\n------------Item or folder deleted---------");
                        break;

                }

                //Display notification identifier
                if(notification is ItemEvent)
                {
                    //The NotificationEvent for an email message is an ItemEvent
                    ItemEvent itemEvent=(ItemEvent)notification;
                    Console.WriteLine("\nItemId:"+ itemEvent.ItemId.UniqueId);
                    Item NewItem=Item.Bind(subscription.Service,itemEvent.ItemId);
                    if(NewItem is EmailMessage)
                    {
                        Console.WriteLine(NewItem.Subject);
                    }

                }
                else
                {
                    //the Notification for a Folder is an FolderEvent
                    FolderEvent folderEvent=(FolderEvent)notification;
                    Console.WriteLine("\nFolderId:"+folderEvent.FolderId.UniqueId);
                }
            }
        }
        static void OnError(object sender,SubscriptionErrorEventArgs args)
        {
            //Handle error conditions.
            Exception e=args.Exception;
            Console.WriteLine("\n-----Error-----"+e.Message+"--------");
        }
    }
}

Upvotes: 2

Views: 2781

Answers (1)

oesebus x
oesebus x

Reputation: 11

Here is an example :

       _BackroundSyncThread = new Thread(streamNotification.SynchronizeChangesPeriodically);       _BackroundSyncThread.Start();

 private void SynchronizeChangesPeriodically()
    {
      while (true)
      {
        try
        {
          // Get all changes from the server and process them according to the business
          // rules.
          SynchronizeChanges(new FolderId(WellKnownFolderName.Calendar));
        }
        catch (Exception ex)
        {
          Console.WriteLine("Failed to synchronize items. Error: {0}", ex);
        }
        // Since the SyncFolderItems operation is a 
        // rather expensive operation, only do this every 10 minutes
        Thread.Sleep(TimeSpan.FromMinutes(10));
      }
    }
    public void SynchronizeChanges(FolderId folderId)
    {
      bool moreChangesAvailable;
      do
      {
        Debug.WriteLine("Synchronizing changes...");
        // Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
        // Only the the ids are requested. Additional properties should be fetched via GetItem calls.
        var changes = _ExchangeService.SyncFolderItems(folderId, PropertySet.FirstClassProperties, null, 512,
                                                       SyncFolderItemsScope.NormalItems, _SynchronizationState);
        // Update the synchronization cookie
        _SynchronizationState = changes.SyncState;

        // Process all changes
        foreach (var itemChange in changes)
        {
          // This example just prints the ChangeType and ItemId to the console
          // LOB application would apply business rules to each item.
          Console.WriteLine("ChangeType = {0}", itemChange.ChangeType);
          Console.WriteLine("Subject = {0}", itemChange.Item.Subject);
        }
        // If more changes are available, issue additional SyncFolderItems requests.
        moreChangesAvailable = changes.MoreChangesAvailable;
      } while (moreChangesAvailable);
    }

The _SynchronizationState field is like a Cookie that contains some informations about your last sync process . So next time the thread will synchronize all the items since the last sync . Hope it helps

Upvotes: 1

Related Questions