Куда идет моя подписка на потоковое вещание?

#c# #exchangewebservices #exchange-server-2010

#c# #exchangewebservices #exchange-server-2010

Вопрос:

Я использую пакет Microsoft Exchange Web Services 1.1 SDK и использую потоковое соединение для подписки на уведомления о новых отправлениях по почте. Для получения уведомлений все работает нормально, но время от времени я получаю ошибки о том, что мой Exchange не может найти мою подписку.

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

 public void Subscribe()
{
    var locateMailbox = new Mailbox
                            {
                                Address = "myemail"
                            };
    var folderId = new FolderId(WellKnownFolderName.Inbox, locateMailbox);
    var foldersToWatch = new[] {folderId};
    StreamingSubscription streamingSubscription =
        _exchangeService.SubscribeToStreamingNotifications(foldersToWatch, EventType.NewMail);
    // Timeout is set at 1 minute intentionally
    var streamingConnection = new StreamingSubscriptionConnection(_exchangeService, 1);

    streamingConnection.AddSubscription(streamingSubscription);

    streamingConnection.OnSubscriptionError  = ResolveError;
    streamingConnection.OnDisconnect  = Reconnect;

    streamingConnection.Open();
}

public void Reconnect(object sender, SubscriptionErrorEventArgs disconnectEventArgs)
{
    if (!((StreamingSubscriptionConnection)sender).IsOpen)
        ((StreamingSubscriptionConnection)sender).Open();
}

public void ResolveError(object sender, SubscriptionErrorEventArgs errorEventArgs)
{
    var streamingSubscriptionConnection =
        (StreamingSubscriptionConnection) sender;
    if (!streamingSubscriptionConnection.IsOpen)
        streamingSubscriptionConnection.Open();
}
  

ServiceLocalException - You must add at least one subscription to this connection before it can be opened.

Это исключение говорит само за себя, и я знаю, что могу просто создать другую подписку внутри Reconnect() . Я надеюсь, что кто-нибудь может помочь мне понять, куда идет подписка. Я не могу представить, что такой продукт, как Exchange 2010, просто потеряет мою подписку. Кроме того, я не могу точно указать на ошибку. Иногда я могу поддерживать свою подписку активной в течение 10 минут, а в других случаях я получаю сообщение об ошибке о том, что моя подписка недействительна через 2-3 минуты.

Как бы то ни было, я использую Exchange 2010 SP1.

Ответ №1:

Если посмотреть на исходный код в Reflector, то, похоже, есть только два способа удалить подписку (помимо удаления StreamingSubscriptionConnection , это вызвать Remove , чего, я полагаю, вы не делаете, или с помощью подписки, возвращающей код ошибки, отличный от ServiceError.ErrorMissedNotificationEvents . Вы можете проверить ошибку, просмотрев errorEventArgs.Exception в вашем ResolveError обработчике. Если это экземпляр ServiceResponseException , приведите его к этому типу и получите ErrorCode свойство. После завершения OnSubscriptionError события подписка автоматически удаляется.

Получение кода ошибки может помочь вам отследить, почему это происходит, но даже если вы не можете это исправить, вы можете определить, когда подписка будет удалена, и асинхронно добавить другую подписку в этом случае.

Комментарии:

1. Я сделал, как вы предложили, и я получаю код ошибки ErrorSubscriptionNotFound . Не уверен, почему, потому что, если я углублюсь в sender аргумент, я увижу, что там есть подписка.

2. Код ошибки — это ошибка, пришедшая с сервера. Когда вы детализируете и видите, что подписка все еще существует, вы находитесь на клиенте. Это сервер, который не может найти подписку. Я предполагаю, что сервер отменил подписку примерно через минуту, потому что вы дали тайм-аут всего в одну минуту. Попробуйте увеличить время ожидания и посмотрите, по-прежнему ли возникает проблема. В любом случае, почему вы намеренно использовали минутный тайм-аут?

3. Я установил тайм-аут на одну минуту, потому что получал ту же ошибку с 30-минутным таймаутом. Вместо того, чтобы ждать несколько наборов по 30 минут, чтобы найти ошибку, я хотел быстрее просматривать ошибки. Но теперь, когда я думаю об этом, я все еще должен кодировать защитным способом, гарантируя, что у меня всегда будет активная подписка. Вы никогда не знаете, когда на сервере возникнет сбой. Спасибо.

4. Похоже, мне придется подождать 6 часов, прежде чем присуждать награду.

Ответ №2:

Я знаю, что об этом спрашивали давным-давно, но я подумал, что опубликую, как я могу обойти ошибку (не могу найти ничего, что объясняет, ПОЧЕМУ это происходит). Кстати, я также использую office 2010 sp1.

Вы можете использовать метод Count () от sender, чтобы проверить, есть ли у вас активная подписка;

 private static void onDisconnect(object sender, SubscriptionErrorEventArgs args)
    {

        StreamingSubscriptionConnection renew = (StreamingSubscriptionConnection)sender;
        if(renew.CurrentSubscriptions.Count() > 0){ //if subscription exists reopen as normal
            renew.Open(); 
        }
        else
        {
            //recreate the whole connection
        }
    }