2013-01-21 2 views
3

EWS에서 여러 명의 명의 도용을 실행하고 각 사람의 일정 (가능한 100 명)에 대한 알림을 수신하려고 할 때 문제가 있습니다. 현재Exchange 웹 서비스 (EWS)의 여러 명의 명의 도용 스레드

나는 다른 모든 사용자를 가장 할 수있는 권한이는 Outlook 계정을 가지고, 모든 ExchangeService - 객체는이 자격 증명

계정 얻을

짧은 버전입니다 나는 고유 ID를 통해 약속에 바인딩 할 때 그것은 하나의 스레드 만 실행하는 한 작동합니다. 자체 구독으로 새 Exchangeservice가 포함 된 새 스레드를 시작하면 Appointment.Bind() 요청에 대한 응답을받지 못합니다.

각각 하나의 스레드 만 사용하여 프로그램의 인스턴스 두 개를 실행하면 새로운 ExchangeService로 새 스레드를 시작하자마자 Appointment.Bind()가 응답을 제공하지 않습니다.

이상한 부분은 2 주일 전에 제대로 작동했지만 갑자기 작동이 멈췄으며 코드가 변경되지 않았습니다.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var x = new OutlookListener("[email protected]"); 
     var y = new OutlookListener("[email protected]"); 
     new Thread(x.Start).Start(); 
     new Thread(y.Start).Start(); 
     while (true) 
     { 

     } 
    } 
} 
class OutlookListener 
{ 
    private ExchangeService _ExchangeService; 
    private AutoResetEvent _Signal; 
    public OutlookListener(string emailToImp) 
    { 
     _ExchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1) 
     { 
      Credentials = new NetworkCredential("[email protected]", "password"), 
      Url = new Uri("exchangeUrl"), 
      ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, emailToImp) 
     }; 
    } 
    public void Start() 
    { 
     var subscription = _ExchangeService.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Calendar }, 
                    EventType.Created); 
     var connection = CreateStreamingSubscription(_ExchangeService, subscription); 
     Console.Out.WriteLine("Subscription created."); 
     _Signal = new AutoResetEvent(false); 
     _Signal.WaitOne(); 
     subscription.Unsubscribe(); 
     connection.Close(); 
    } 

    private StreamingSubscriptionConnection CreateStreamingSubscription(ExchangeService service, StreamingSubscription subscription)                   
    { 
     var connection = new StreamingSubscriptionConnection(service, 30); 
     connection.AddSubscription(subscription); 
     connection.OnNotificationEvent += OnNotificationEvent; 
     connection.OnSubscriptionError += OnSubscriptionError; 
     connection.OnDisconnect += OnDisconnect; 
     connection.Open(); 

     return connection; 
    } 
    private void OnNotificationEvent(object sender, NotificationEventArgs args) 
    { 
     // Extract the item ids for all NewMail Events in the list. 
     var newMails = from e in args.Events.OfType<ItemEvent>() 
         where e.EventType == EventType.Created 
         select e.ItemId; 

     foreach (var newMail in newMails) 
     { 
      var appointment= Appointment.Bind(_ExchangeService, newMail); //This is where I dont get a response! 
      Console.WriteLine(appointment.Subject); 
     } 
    } 
    private void OnSubscriptionError(object sender, SubscriptionErrorEventArgs args) 
    { 
    } 
    private void OnDisconnect(object sender, SubscriptionErrorEventArgs args) 
    { 
    } 
} 

어떤 제안 :

나는 내 문제의 빠른 데모를 만들었습니다?

답변

1

왜 여러 개의 스레드가 필요합니까?

필자가 가장하고 싶은 각 이메일에 대한 smtpaddress를 기반으로 서비스 사전을 작성했으며 모두 가입합니다. 모두 한 스레드에서 발생할 수 있으며 모든 사용자의 모든 알림은 OnNotificationEvent에서 처리됩니다. [이 코드는 LOGIC 보여 그냥 AND FULL COMPILATION AND RUN FOR 완료되지] 여기 Services.First(). 값은 모든 다른 사용자를 사칭 할 수있는 서비스인지

  var service = new ExchangeService(exchangeVersion); 

      var serviceCred = ((System.Net.NetworkCredential)(((WebCredentials)(Services.First().Value.Credentials)).Credentials)); 

      service.Credentials = new WebCredentials(serviceCred.UserName, serviceCred.Password); 

      service.AutodiscoverUrl(userSmtp, RedirectionUrlValidationCallback); 

      service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, userSmtp); 

      Services.Add(userSmtp, service); 

주 및 사용자 번호로 복제됩니다. 모든 서비스가 가입 후

private void SubscribeToService(ExchangeService service) 
     { 

       if (service.ImpersonatedUserId == null) 
        return; 
       if (service.Url == null) 
        return; 

       var serviceName = service.ImpersonatedUserId.Id; 


       var streamingSubscription = 
             service.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.DeletedItems, WellKnownFolderName.Calendar }, 
                EventType.FreeBusyChanged, EventType.Moved, EventType.Created, EventType.Modified); 

       if (!Connections.ContainsKey(service.Url)) 
       { 
        Connections.Add(service.Url, new StreamingSubscriptionConnection(service, 30)); 

       } 
       var connection = Connections[service.Url]; 

       CloseConnection(connection); 

       if (!_subscriptions.ContainsKey(serviceName)) 
       { 
        _subscriptions.Add(serviceName, streamingSubscription); 
        connection.AddSubscription(streamingSubscription); 
       } 

      } 

     } 

이 모든 일어날 수에 따라대로

foreach (var service in Services.Values) 
      { 
       SubscribeToService(service); 
      } 

및 SubscribeToService에 대한 정의 (주는 이제 각 서비스는 다른 사용자를 가장한다) 하나의 스레드, 그리고 내 대답은 당신을 도울 수 있기를 바랍니다. 건배

1

나는 동일한 문제를 가지고 있으며, 내 EWS sol ution은 두 가지 요인에 의해 제한되었습니다. System.Net.ServicePointManager.DefaultConnectionLimit은 기본적으로 2로 설정되어 있으며 Exchange Online의 제한 정책과 일치하도록 20으로 변경되었습니다.

둘째 ExchangeService 개체의 ConnectionGroupName 속성은 DefaultConnectionLimit 속성과 동시에 연결이 제한되는 여러 관련 그룹에 연결을 풀링하는 데 사용할 수 있습니다.

설정을 재정의하는 방법은 만드는 각 ExchangeService 개체에 대해 ConnectionGroupName 속성을 고유 값으로 설정하는 것입니다.

ExchangeService exchangeService = new ExchangeService() 
{ 
    ConnectionGroupName = Guid.NewGuid().ToString() 
}; 
+0

Setting System.Net.ServicePointManager.DefaultConnectionLimit을 20으로 수정했습니다. :) – MojoDK

관련 문제