Клиент WCF Silverlight получает 404 не найден ответ на сообщение опроса
В конце концов WCF дуплекс Silverlight 4 клиент начинает получать 404 Not Found
ошибки для сообщений опроса, сразу после отправки опроса из службы WCF клиенту Silverlight, иногда это происходит для второго опроса, иногда подключение работает часами или даже днями, но в большинстве случаев происходит сбой в первые минуты.
! И что интересно, проблема похожа на известную ошибку Silverlight 4 при использовании MaxMessagesPerPoll
дуплексный режим и решение описаны здесь и здесь, но я использую SingleMessagePerPoll
Режим. В любом случае я пытался использовать ClientStack
как и предполагалось, но ничего не изменилось.
Общий поток:
- SL клиент выполняет метод сервиса WCF, получил ответ
- Затем немедленно клиент SL начинает отправлять сообщения опроса в службу, а затем получает исключение для второго или Ns сообщения опроса.
System.Net.WebException: удаленный сервер возвратил ошибку: NotFound
- Скрипач покажет только пусто
404
ответ на сообщение опроса - Затем возникло событие "Ошибка канала клиента"
Я пытаюсь переподключить SL-клиент после такой ошибки, повторная попытка повторного подключения:
- Справиться
Faulted
событие - Отписаться от всех событий канала, как
Closed/Closing/Opened/Opening
- Правильно закройте канал, используя
try { close } catch { abort }
- Все ниже в новой теме:(мне кажется, это работает немного стабильно - см. Эту статью)
- Подождите 45-70 секунд
- Используя то же самое
DuplexChannelFactory<T>
например, создать новый канал, подписаться на все события канала только для целей регистрации - Выполнить метод службы WCF
После 1-10 повторных попыток (~1-10 минут) клиент в конечном итоге подключается к серверу и продолжает нормальный опрос.
В журнале службы WCF я вижу, что он получает все запросы очистки, обработанные без каких-либо исключений, поэтому кажется, что что-то происходит на стороне клиента Silverlight.
Общая информация:
- .NET Framework 4.0
- PollingDuplex
- Асинхронные методы WCF
- Служба WCF, размещенная в IIS 6.0
- Клиент Silverligth 4
- Клиентская ОС: Windows XP SP2
- Серверная ОС: Windows 2003 R2 SP2
- NTLM аутентификация
- DuplexMode: SingleMessagePerPoll
- Существует другая служба WCF, которая выполняет запрос / ответ до того, как моя служба начинает работать, она не использует дуплексную связь
- На клиентском сервисе SL я регистрирую все в пользовательском интерфейсе, чтобы видеть все события и иметь время для каждого конкретного события.
- Нет ошибок в журналах IIS, журналах событий сервера
Клиент:
var binaryBinding = new BinaryMessageEncodingBindingElement();
binaryBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
var httpbindingElement = new HttpTransportBindingElement
{
MaxReceivedMessageSize = 131072
};
var pollingDuplexBindingElement = new PollingDuplexBindingElement
{
ClientPollTimeout = new TimeSpan(0, 0, 1, 30),
InactivityTimeout = new TimeSpan(0, 8, 0, 0),
};
_binding = new CustomBinding(
pollingDuplexBindingElement,
binaryBinding,
httpbindingElement)
{
SendTimeout = new TimeSpan(0, 0, 0, 45),
CloseTimeout = new TimeSpan(0, 0, 0, 25),
ReceiveTimeout = new TimeSpan(0, 8, 0, 0),
OpenTimeout = new TimeSpan(0, 0, 0, 45)
};
httpbindingElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
var endpoint = new EndpointAddress(_endpointAddress);
_channelFactory = new DuplexChannelFactory<TWebService>(
new InstanceContext(instanceOfClientServiceClass),
_binding,
endpoint);
// then this factory used to create a new channels
// Also for a new channel I'm setting OpTimeout
var contextChannel = newChannel as IContextChannel;
if (contextChannel != null)
{
contextChannel.OperationTimeout = TimeSpan.FromSeconds(45);
}
Сервер:
- WCF, PerSession, многопоточный
- Все потокобезопасно
- Нет исключений службы сервера во время выполнения
- Много регистрации, поэтому я вижу, что происходит на сервисе
- Все трассировки WCF включены с помощью switchValue
All
ничего подозрительного
<binding name="customName"
sendTimeout="00:01:00"
receiveTimeout="08:00:00"
openTimeout="00:01:00"
closeTimeout="00:00:35">
<pollingDuplex
inactivityTimeout="08:00:00"
serverPollTimeout="00:01:00" />
<binaryMessageEncoding />
<httpTransport authenticationScheme="Ntlm"
maxReceivedMessageSize="131072">
</httpTransport>
</binding>
<behavior name="customBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling
maxConcurrentCalls = "500"
maxConcurrentSessions = "500"
maxConcurrentInstances = "500" />
</behavior>
2 ответа
Во время исследования проблемы, описанной в этом посте Stackru, статический конструктор, дважды вызванный для службы PerSession WCF, обнаружил, что Polling Duplex
начать работать стабильно, когда я перешел IIS
конфигурация для базового AppPool
использовать один рабочий процесс, а не 2
как было указано ранее. Я не уверен почему 2
был установлен ранее, так как у меня нет этого сервера, но в любом случае это то, что у меня сейчас - несколько клиентов Silverlight, запущенных на одной машине, работают стабильно и опрашивают опросы и нет 404
ошибки, все клиенты переподключаются в 1
попытка после IIS перезапускается и перезагружается...
См. Настройки пула приложений для более подробной информации.
TL;DR: когда размещенный в IIS WCF находится в AppPool, в котором имеется более одного рабочего процесса, дуплекс опроса становится нестабильным. Таким образом, в случае высокой нагрузки IIS запустил второй процесс и также начал создавать экземпляры службы WCF во втором процессе, поэтому я столкнулся с ситуацией, когда сеанс клиента был создан в одном процессе, но кажется, что опрос иногда достиг другого процесса, который не знает о текущем соединение / сеанс, поэтому начните отказываться от таких сообщений и всей ошибки соединения.
Таким образом, дуплекс Polling по своей структуре не масштабируется между несколькими процессами в рамках одного сервера IIS и AppPool, другими словами, если у вас более одного рабочего процесса - это среда WebGarden, а дуплекс не масштабируется в веб-фермах и садах.
Если кажется, что все работает нормально, возможно, это проблема сетевой инфраструктуры / конфигурации (например, настройка DNS). Вы получаете ту же проблему при локальном запуске или использовании IP-адреса вместо имени хоста?
Подобная проблема также может возникнуть, если на сайте в IIS настроено несколько привязок (подробности см. Здесь: http://blogs.msdn.com/b/rampo/archive/2008/02/11/how-can-wcf-support-multiple-iis-binding-specified-per-site.aspx)
Другое дело, как вы общались с сервера клиентам. Если вы перебираете клиентов в цикле и вызываете методы обратного вызова один за другим, вы можете получить тайм-ауты, которые будут отображаться как 404. Обычно обратный вызов должен вызываться в фоновых потоках (по одному на клиента).
В зависимости от того, как вы осуществляете связь, это также может быть вызвано взаимоблокировкой (когда поток пользовательского интерфейса участвует в отправке / получении сообщений / обратных вызовов в службу и из службы).