Несколько подписок PushNotification некоторые работают правильно, а некоторые нет

Я попытался опубликовать это на форуме разработчиков Exchange, но не получил никаких ответов, поэтому попробую здесь. Ссылка на форум

У меня есть службы Windows, которые запускаются каждые пятнадцать минут, чтобы узнать, есть ли какие-либо подписки, которые необходимо создать или обновить. Я использую Managed API v1.1 против Exchange 2007 SP1. У меня есть таблица, в которой хранятся все пользователи, которым нужен мониторинг почтовых ящиков. Так что, когда уведомление приходит в «службу прослушивания», я могу найти пользователя и получить доступ к сообщению, чтобы зарегистрировать его в приложении, которое мы создаем. В таблице у меня есть следующие столбцы, в которых хранится информация о подписке:

  1. SubscriptionId - VARCHAR (MAX)
  2. Водяной знак - VARCHAR (MAX)
  3. LastStatusUpdate - DATETIME

Мои службы вызывают функцию, которая запрашивает данные необходимо (в зависимости от того, какую функцию он выполняет). Если у пользователя еще нет подписки, служба перейдет и создаст ее. Я использую олицетворение для доступа к почтовым ящикам. Вот мой метод «ActiveSubscription», который запускается, когда пользователю требуется создать или обновить подписку.

private void ActivateSubscription(User user)
{
  if (user.ADGUID.HasValue)
  {
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Settings.ActiveDirectoryServerName, Settings.ActiveDirectoryRootContainer);

    using (UserPrincipal up = UserPrincipal.FindByIdentity(ctx, IdentityType.Guid, user.ADGUID.Value.ToString()))
    {
      ewService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SID, up.Sid.Value);
    }
  }
  else
  {
    ewService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, user.EmailAddress);
  }

  PushSubscription pushSubscription = ewService.SubscribeToPushNotifications(
    new FolderId[] { WellKnownFolderName.Inbox, WellKnownFolderName.SentItems },
    Settings.ListenerService, 30, user.Watermark,
    EventType.NewMail, EventType.Created);

  user.Watermark = pushSubscription.Watermark;
  user.SubscriptionID = pushSubscription.Id;
  user.SubscriptionStatusDateTime = DateTime.Now.ToLocalTime();

  _users.Update(user);
}

Мы также запустили следующий командлет, чтобы дать пользователю, к которому мы обращаемся к EWS, возможность олицетворять на сервере Exchange.

Get-ExchangeServer | where {$_.IsClientAccessServer -eq $TRUE} | ForEach-Object {Add-ADPermission -Identity $_.distinguishedname -User (Get-User -Identity mailmonitor | select-object).identity -extendedRight ms-Exch-EPI-Impersonation}

Приведенный выше код «ActivateSubscription» работает должным образом. По крайней мере, я так думал. Когда я тестировал его, он контролировал мой почтовый ящик, и он отлично работал. Единственная проблема, которую мне пришлось решить, заключалась в том, что подписка срабатывала дважды, когда элемент был новым письмом в папке «Входящие», я получал уведомление о событии NewMail и событии Created. Я реализовал обходной путь, который проверяет, не было ли сообщение еще зарегистрировано в моей службе прослушивания. Все сработало отлично.

Сегодня мы начали тестировать два почтовых ящика, за которыми ведется наблюдение одновременно. Два почтовых ящика были моими, а еще один почтовый ящик разработчиков. Мы обнаружили самое странное поведение. Моя подписка сработала, как ожидалось. Но его не t, входящая часть его подписки работает правильно, но ни одно электронное письмо, которое он отправил службе прослушивания, никогда не было отправлено с уведомлением. Глядя на свойства почтового ящика на Exchange, я не вижу разницы между его почтовым ящиком и моим. Мы даже сравнили параметры / настройки в Outlook. Я не вижу причин, почему это работает в моем почтовом ящике, а не в его.

Есть ли что-то, чего мне не хватает при создании подписки. Я не думал, что это было, так как моя подписка работает должным образом.

Мой код службы прослушивания работает отлично. Я поместил код ниже на тот случай, если кто-то захочет увидеть это, чтобы убедиться, что это не проблема.

Заранее спасибо, Терри

Код службы прослушивания:

/// 
/// Summary description for PushNotificationClient
/// 
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class PushNotificationClient : System.Web.Services.WebService, INotificationServiceBinding
{
  ExchangeService ewService = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

  public PushNotificationClient()
  {
    //todo: init the service.
    SetupExchangeWebService();
  }

  private void SetupExchangeWebService()
  {
    ewService.Credentials = Settings.ServiceCreds;
    try
    {
      ewService.AutodiscoverUrl(Settings.AutoDiscoverThisEmailAddress);
    }
    catch (AutodiscoverRemoteException e)
    {
      //log auto discovery failed
      ewService.Url = Settings.ExchangeService;
    }
  }

  public SendNotificationResultType SendNotification(SendNotificationResponseType SendNotification1)
  {
    using (var _users = new ExchangeUser(Settings.SqlConnectionString))
    {
      var result = new SendNotificationResultType();

      var responseMessages = SendNotification1.ResponseMessages.Items;
      foreach (var responseMessage in responseMessages)
      {
        if (responseMessage.ResponseCode != ResponseCodeType.NoError)
        {
          //log error and unsubscribe.
          result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
          return result;
        }

        var sendNoficationResponse = responseMessage as SendNotificationResponseMessageType;
        if (sendNoficationResponse == null)
        {
          result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
          return result;
        }

        var notificationType = sendNoficationResponse.Notification;
        var subscriptionId = notificationType.SubscriptionId;
        var previousWatermark = notificationType.PreviousWatermark;

        User user = _users.GetById(subscriptionId);
        if (user != null)
        {
          if (user.MonitorEmailYN == true)
          {
            BaseNotificationEventType[] baseNotifications = notificationType.Items;

            for (int i = 0; i < notificationType.Items.Length; i++)
            {
              if (baseNotifications[i] is BaseObjectChangedEventType)
              {
                var bocet = baseNotifications[i] as BaseObjectChangedEventType;
                AccessCreateDeleteNewMailEvent(bocet, ref user);
              }
            }

            _PreviousItemId = null;
          }
          else
          {
            user.SubscriptionID = String.Empty;
            user.SubscriptionStatusDateTime = null;
            user.Watermark = String.Empty;
            _users.Update(user);

            result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
            return result;
          }

          user.SubscriptionStatusDateTime = DateTime.Now.ToLocalTime();
          _users.Update(user);
        }
        else
        {
          result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
          return result;
        }
      }

      result.SubscriptionStatus = SubscriptionStatusType.OK;
      return result;
    }
  }

  private string _PreviousItemId;
  private void AccessCreateDeleteNewMailEvent(BaseObjectChangedEventType bocet, ref User user)
  {
    var watermark = bocet.Watermark;
    var timestamp = bocet.TimeStamp.ToLocalTime();
    var parentFolderId = bocet.ParentFolderId;

    if (bocet.Item is ItemIdType)
    {
      var itemId = bocet.Item as ItemIdType;
      if (itemId != null)
      {
        if (string.IsNullOrEmpty(_PreviousItemId) || (!string.IsNullOrEmpty(_PreviousItemId) && _PreviousItemId != itemId.Id))
        {
          ProcessItem(itemId, ref user);
          _PreviousItemId = itemId.Id;
        }
      }
    }

    user.SubscriptionStatusDateTime = timestamp;
    user.Watermark = watermark;
    using (var _users = new ExchangeUser(Settings.SqlConnectionString))
    {
      _users.Update(user);
    }

  }

  private void ProcessItem(ItemIdType itemId, ref User user)
  {
    try
    {
      ewService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, user.EmailAddress);
      EmailMessage email = EmailMessage.Bind(ewService, itemId.Id);
      using (var _entity = new SalesAssistantEntityDataContext(Settings.SqlConnectionString))
      {
        var direction = EmailDirection.Incoming;
        if (email.From.Address == user.EmailAddress)
        {
          direction = EmailDirection.Outgoing;
        }


        int? bodyType = (int)email.Body.BodyType;

        var _HtmlToRtf = new HtmlToRtf();
        var message = _HtmlToRtf.ConvertHtmlToText(email.Body.Text);

        bool? IsIncoming = Convert.ToBoolean((int)direction);

        if (IsIncoming.HasValue && IsIncoming.Value == false)
        {
          foreach (var emailTo in email.ToRecipients)
          {
            _entity.InsertMailMessage(email.From.Address, emailTo.Address, email.Subject, message, bodyType, IsIncoming);
          }
        }
        else
        {
          if (email.ReceivedBy != null)
          {
            _entity.InsertMailMessage(email.From.Address, email.ReceivedBy.Address, email.Subject, message, bodyType, IsIncoming);
          }
          else
          {
            var emailToFind = user.EmailAddress;
            if (email.ToRecipients.Any(x => x.Address == emailToFind))
            {
              _entity.InsertMailMessage(email.From.Address, emailToFind, email.Subject, message, bodyType, IsIncoming);
            }
          }
        }
      }
    }
    catch(Exception e)
    {
      //Log exception 
      using (var errorHandler = new ErrorHandler(Settings.SqlConnectionString))
      {
        errorHandler.LogException(e, user.UserID, user.SubscriptionID, user.Watermark, user.SubscriptionStatusDateTime);
      }
      throw e;
    }
  }

}

6
задан Terry Nederveld 24 March 2011 в 12:56
поделиться