WCF, BasicHttpBinding: остановка новых подключений, но продолжение существующих подключений

.NET 3.5, VS2008, служба WCF с использованием BasicHttpBinding

У меня есть служба WCF, размещенная в службе Windows. Когда служба Windows закрывается из-за обновлений, планового обслуживания и т. Д., Мне нужно изящно завершить свою службу WCF. Служба WCF имеет методы, выполнение которых может занять до нескольких секунд, а типичный объем составляет 2-5 вызовов метода в секунду. Мне нужно завершить службу WCF таким образом, чтобы можно было завершить любые ранее вызванные методы, при этом отказывая в новых вызовах. Таким образом, я могу достичь спокойного состояния через ~ 5-10 секунд и затем завершить цикл выключения моей службы Windows.

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

Вот последовательность событий:

Клиент вызывает метод на службе, используя сгенерированный VS класс проксиСервис начинает выполнение метода сервисаСервис получает запрос на отключениеСервис вызывает ServiceHost.Close (или BeginClose)Клиент отключен и получает исключение System.ServiceModel.CommunicationExceptionСервис завершает метод обслуживания.В конце концов служба обнаруживает, что ей больше не нужно выполнять (через логику приложения), и завершает работу.

Мне нужно, чтобы клиентские соединения оставались открытыми, чтобы клиенты знали, что их методы обслуживания завершены успешно. Сейчас они просто получают закрытое соединение и не знают, успешно ли завершен метод обслуживания. До использования WCF я использовал сокеты и мог сделать это, управляя Socket напрямую. (то есть остановите цикл Accept, продолжая получать и отправлять)

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

Есть ли способ сделать это в WCF?

Вещи, которые я пробовал:

ServiceHost.Close () - сразу закрывает клиентовServiceHost.ChannelDispatchers - вызывать Listener.Close () для каждого - кажется, ничего не делаетServiceHost.ChannelDispatchers - вызывать CloseInput () для каждого - сразу же закрывать клиентовOverride ServiceHost.OnClosing () - позволяет мне отложить закрытие до тех пор, пока я не решу, что закрытие нормально, но в это время разрешены новые соединенияУдалите конечную точку, используятехника, описанная здесь, Это уничтожает все.Запуск сетевого анализатора для наблюдения ServiceHost.Close (). Хост просто закрывает соединение, ответ не отправляется.

Спасибо

редактироватьК сожалению, я не могу реализовать консультативный ответ на уровне приложения о том, что система выключается, потому что клиенты на местах уже развернуты. (Я контролирую только сервис, а не клиентов)

редактироватьЯ использовал Redgate Reflector, чтобы посмотреть на реализацию Microsoft ServiceHost.Close. К сожалению, это вызывает некоторыеinternal вспомогательные классы, к которым мой код не может получить доступ.

редактироватьЯ не нашел полного решения, которое искал, но предложение Бенджамина использовать IMessageDispatchInspector для отклонения запросов до входа в сервисный метод было ближе всего.

Ответы на вопрос(8)

Ваш ответ на вопрос