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 для отклонения запросов до входа в сервисный метод было ближе всего.