WCF Publish / Subscribe: Как обработать тайм-аут на стороне клиента, чтобы не пропустить информацию? - PullRequest
2 голосов
/ 27 мая 2011

У меня есть простая публикация и подписка WCF, на основе этого примера . Я использую netTcpBinding с включенной надежной сессией. С функциональностью все работает нормально (подписанные клиенты получают опубликованные данные, как и ожидалось), но в какой-то момент время соединения истекает, если оно какое-то время простаивало. Я могу настроить издателя на повторное подключение по таймауту, но подписанные клиенты будут потеряны. Есть ли способ вернуть их? Я бы предпочел не просто увеличивать время ожидания, так как это может вызвать другие проблемы.

1 Ответ

0 голосов
/ 10 июня 2011

Решение, которое я в итоге придумал, состояло в том, чтобы назначить уникальный идентификатор каждому опубликованному сообщению и кэшировать опубликованное сообщение в сервисном адаптере (там же, где я хранил обратные вызовы для подписанных клиентов. Всякий раз, когда я опубликовав сообщение, подписчики получат сообщения и с соответствующим уникальным идентификатором. Затем подписчики могут использовать событие channel.Faults для повторного подключения и повторной подписки на услугу специальным методом, который принимает последний полученный идентификатор сообщения в качестве параметр.

Сервисный код:

    /// <summary>
    /// Operation used by the subscriber to subscribe to events published.
    /// </summary>
    public void Resubscribe(int lastReceivedMessageId)
    {
        // Get callback contract
        IPubSubCallback callback = OperationContext.Current.GetCallbackChannel<IPubSubCallback>();
        ThreadPool.QueueUserWorkItem(delegate(object state)
        {
            adapter.Resubscribe(lastReceivedMessageId, callback);
        }); 
    }

Код адаптера:

/// <summary>
    /// Operation used by the subscriber to resubscribe to events published.
    /// </summary>
    public void Resubscribe(int lastReceivedMessageId, IPubSubCallback callback)
    {
        try
        {
            // Send the subscriber any missed messages
            foreach (KeyValuePair<int, string> missedMessage in publishedMessages.Where(x => x.Key > lastReceivedMessageId))
            {
                callback.MessagePublished(missedMessage.Value, missedMessage.Key);
            }

            // Add the subscriber callback to the list of active subscribers
            if (!callbacks.Contains(callback))
            {
                callbacks.Add(callback);
            }
        }
        catch
        {
            // ignore subscription, callbacks failed again
        }
    }

Служба может затем определить, что пропустил клиент, и отправить эти сообщения в правильном порядке.

Мне кажется, это решение работает хорошо, но у меня есть ощущение, что должен быть лучший способ сделать это. Комментарии / дополнительные ответы очень приветствуются! :)

...