title: EWS Notification Hub for multiple users
body: <p>I am trying to create a service to push exchange notifications to asp.net applications, eventually using SignalR.</p>
  
  <p>My plan is to create a notification hub that subscribes each user as they log in to the asp application and listen for notifications for them. As a notification is received the second part of the project is to then use signalR to only send the correct notifications to each user. Once they log out or time out the notification hub will unsubscribe them.</p>
  
  <p>So far I have done a little basic testing and can receive notifications in a little console app for myself with my credentials hard coded. What I am struggling with is how to do this for multiple people simultaneously. For example would I have to create separate threads of this for each user or is there a better way?</p>
  
  <p>I guess regardless I am going to have to use impersonation rather than holding each users credentials right? I'm also going to have to work out a way to auto refresh the timeout for each user if they have an active session.</p>
  
  <p>Below is a little code I found and have been playing with, I would be grateful for any ideas or example anyone could share of how I could best achieve this.</p>
  
  <p>Many thanks </p>
  
  <p>Andy</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net;
  using System.Threading.Tasks;
  using Microsoft.Exchange.WebServices.Data;
  
  namespace ConsoleApplication1
  {
      class Program
      {
          static void Main(string[] args)
          {
  
                  ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
                  service.Url = new Uri("https://server/EWS/Exchange.asmx");
                  service.Credentials = new NetworkCredential("user", "pass", "domain");
                  SetStreamingNotifications(service); 
                  while (true)
                  { }
  
  
          }
  
          static void SetStreamingNotifications(ExchangeService service)
          {
              // Subscribe to streaming notifications on the Inbox folder, and listen
              // for "NewMail", "Created", and "Deleted" events.
              StreamingSubscription streamingsubscription = service.SubscribeToStreamingNotifications(
                  new FolderId[] { WellKnownFolderName.Calendar, WellKnownFolderName.Inbox },
                  EventType.Created,
                  EventType.Modified);
  
              StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(service, 9);
  
              connection.AddSubscription(streamingsubscription);
              // Delegate event handlers.
              connection.OnNotificationEvent +=
                  new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
              connection.OnSubscriptionError +=
                  new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
              connection.OnDisconnect +=
                  new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect);
              connection.Open();
  
              Console.WriteLine("--------- StreamSubscription event -------");
          }
  
          static private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
          {
              // Cast the sender as a StreamingSubscriptionConnection object.          
              StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
              // Ask the user if they want to reconnect or close the subscription.
              ConsoleKeyInfo cki;
              Console.WriteLine("The connection to the subscription is disconnected.");
              Console.WriteLine("Do you want to reconnect to the subscription? Y/N");
              while (true)
              {
                  cki = Console.ReadKey(true);
                  {
                      if (cki.Key == ConsoleKey.Y)
                      {
                          connection.Open();
                          Console.WriteLine("Connection open.");
                          break;
                      }
                      else if (cki.Key == ConsoleKey.N)
                      {
                          // The ReadKey in the Main() consumes the E.
                          Console.WriteLine("\n\nPress E to exit");
                          break;
                      }
                  }
              }
          }
  
          static void OnEvent(object sender, NotificationEventArgs args)
          {
              StreamingSubscription subscription = args.Subscription;
  
              // Loop through all item-related events.
              foreach (NotificationEvent notification in args.Events)
              {
  
                  switch (notification.EventType)
                  {
                      case EventType.NewMail:
                          Console.WriteLine("\n-------------Mail created:-------------");
                          break;
                      case EventType.Created:
                          Console.WriteLine("\n-------------Item or folder created:-------------");
                          break;
                      case EventType.Deleted:
                          Console.WriteLine("\n-------------Item or folder deleted:-------------");
                          break;
                  }
                  // Display the notification identifier.
                  if (notification is ItemEvent)
                  {
                      // The NotificationEvent for an e-mail message is an ItemEvent.
                      ItemEvent itemEvent = (ItemEvent)notification;
                      Console.WriteLine("\nItemId: " + itemEvent.ItemId.UniqueId);
  
                  }
                  else
                  {
                      // The NotificationEvent 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 + "-------------");
          }
      }
  }
  </code></pre>