Как сервер WCF информирует клиента WCF об изменениях?(Лучшее решение, чем простой опрос, напримерКомета или длительный опрос)

StackOverflow https://stackoverflow.com/questions/1700917

Вопрос

смотрите также "ФОС толчок к клиенту через брандмауэр"

Мне нужно иметь клиент WCF, который подключается к серверу WCF, затем, когда некоторые данные Изменения на сервере клиентам необходимо Обновить его отображение.

Поскольку между клиентами и сервером, скорее всего, будет установлен брандмауэр.

  • Все коммуникации должны осуществляться по протоколу HTTP
  • Сервер не может выполнить (физический) исходящий вызов клиенту.

Поскольку я пишу как клиент, так и сервер, мне не нужно ограничивать решение только использованием soap и т.д.


Я ищу встроенный порт для "длительный опрос" / "Комета" и т. д


Спасибо за самый информативный ответ от Дрю Марша о том, как реализовать длительный опрос в WCF.Однако я думал, что основным “преимуществом” WCF было то, что вы могли бы делать подобные вещи, просто настроив каналы, которые будут использоваться в файле конфигурации. Например, мне нужен канал, который логически двусторонний, но только физически входящий.

Это было полезно?

Решение

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


Основы:

  1. Во-первых, решите, какой продолжительности вы хотите, чтобы был каждый "длинный опрос".Ради аргументации я собираюсь выбрать 5-минутные тайм-ауты.
  2. На стороне клиента измените привязку sendTimeout="00:05:00".
  3. Точно так же, как при использовании XMLHttpRequest (XHR) для длительного опроса, когда тайм-аут действительно наступает, вам нужно будет обнаружить его и повторно отправить следующий запрос на опрос.В WCF это довольно просто, потому что существует конкретное исключение, TimeoutException, который вы можете перехватить , чтобы легко обнаружить , что это была проблема противкакое-то другое исключение.
  4. В зависимости от того, как вы размещаете свою службу WCF, вам нужно будет обязательно настроить себя так, чтобы обработка продолжалась до 5 минут.С точки зрения чистого WCF вам нужно убедиться, что вы установили receiveTimeout="00:05:00".Однако, если вы размещаете внутри ASP.NET вам также нужно будет настроить ASP.NET среду выполнения для увеличения времени ожидания, что выполняется с помощью <httpRuntime executionTimeout="300" /> (примечание: измерения для этого атрибута приведены в секундах).

Быть эффективным в работе с клиентом

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

Если вы создаете свои сервисные контракты вручную, я бы посоветовал проверить этот раздел в MSDN на OperationContractAttribute.AsyncPattern для получения подробной информации о том, как добавить BeginXXX/EndXXX асинхронная пара методов для каждого из ваших вызовов.Однако, если вы используете svcutil чтобы сгенерировать ваши операционные контракты для вас, все, что вам нужно сделать для создания асинхронных методов, - это передать /async опция в командной строке.Для получения более подробной информации по этой теме, ознакомьтесь с разделом Синхронный и асинхронный в MSDN.

Теперь, когда вы определили свои асинхронные операции, шаблон очень похож на работу с XHR.Вы называете BeginXXX метод, к которому вы переходите ан AsyncCallback делегироватьBeginXXX метод вернет вам IAsyncResult, который вы можете либо сохранить, если хотите иметь возможность ожидать выполнения операции (в более сложных сценариях), либо проигнорировать, и тогда инфраструктура WCF асинхронно отправит запрос на сервер и будет ждать ответа за кулисами.Когда получен ответ или возникает исключение, обратный вызов, который вы передали в BeginXXX будет вызван метод.Внутри этого метода обратного вызова вам нужно вызвать соответствующий EndXXX метод, проходящий в IAsyncResult это передается вам в руки.Во время звонка в EndXXX метод вам необходимо использовать обработку исключений для устранения любого вида логической ошибки, которая могла возникнуть при вызове метода, но это также то место, где вы теперь сможете перехватить TimeoutException мы говорили об этом ранее.Предполагая, что вы получили хороший ответ, данные будут возвращены из EndXXX позвоните, и вы сможете отреагировать на эти данные любым разумным способом.

ПРИМЕЧАНИЕ: Единственное, что следует иметь в виду относительно этого шаблона, - это характер пронизывания.Асинхронные обратные вызовы из WCF будут получены в потоке из управляемый пул потоков.Если вы планируете обновить пользовательский интерфейс с помощью такой технологии, как WPF или WinForms, вам нужно убедиться, что вы перенаправляете вызовы обратно в поток пользовательского интерфейса с помощью Invoke или BeginInvoke методы.

Быть эффективным на сервере

Если мы собираемся беспокоиться об эффективности работы клиента, то нам следует беспокоиться вдвойне, когда дело доходит до сервера.Очевидно, что такой подход предъявляет больше требований к стороне сервера, потому что соединение должно оставаться открытым и ожидающим до тех пор, пока не появится причина отправить уведомление обратно клиенту.Проблема здесь заключается в том, что вы хотите связать среду выполнения WCF только с обработкой тех клиентов, которым на самом деле отправляется событие.Все остальное должно просто спать, ожидая, когда произойдет событие.К счастью, тот же самый асинхронный шаблон, который мы только что использовали на стороне клиента, работает и на стороне сервера.Однако сейчас есть существенное отличие:сейчас ты необходимо вернуть IAsyncResult (и, таким образом, WaitHandle) из BeginXXX метод, о котором среда выполнения WCF затем будет ждать сигнала, прежде чем вызывать ваш EndXXX способ.

Ты будешь не найдите много документации внутри MSDN, отличной от ссылок, которые я уже предоставил ранее, и, к сожалению, их примеры по написанию асинхронной службы менее чем полезны.Это сказало, Вэньлун Дон написал статью о масштабировании сервисов WCF с помощью асинхронной модели некоторое время назад, что я настоятельно рекомендую вам проверить.

Помимо этого, я, честно говоря, не могу дать слишком много советов о том, как лучше всего реализовать асинхронную модель на стороне сервера для вас, потому что это полностью зависит от того, из какого источника данных будут исходить ваши события в первую очередь.File I/O?Очередь сообщений?База данных?Какое-то другое проприетарное программное обеспечение с собственной службой обмена сообщениями, которое вы пытаетесь прикрыть фасадом?Я не знаю, но все они должны предлагать собственные асинхронные модели, на основе которых вы можете создать свой собственный сервис, чтобы сделать его максимально эффективным.

Обновленный Рецепт

Поскольку это, кажется, популярный ответ, я решил, что мне следует вернуться сюда и предоставить обновленную информацию, учитывая недавние изменения в ландшафте.На данный момент существует библиотека .NET, которая называется СигналР который обеспечивает именно эту функциональность и, безусловно, является тем, как я бы рекомендовал реализовать любое такое взаимодействие с сервером.

Другие советы

Если бы сервер мог установить исходящее соединение с сервисной шиной, вы могли бы внедрить тип обратного вызова.Таким образом, клиенту / серверу вообще не нужно было бы знать друг о друге, только о полагающейся служебной шине.Видишь Служебная шина .NET

Вам захочется заглянуть в Привязка WSDualHttpBinding

Привязка WSDualHttpBinding обеспечивает ту же поддержку протоколов веб-служб что и привязка wsHttpBinding, но для использования с двусторонними контрактами.WSDualHttpBinding поддерживает только безопасность SOAP и требует надежного обмена сообщениями.Это привязка требует, чтобы у клиента был общедоступный URI, который обеспечивает обратный вызов конечная точка для службы.Это предоставляется ClientBaseAddress.A двойная привязка предоставляет IP-адрес клиента сервису.Клиент должен использовать систему безопасности, чтобы гарантировать, что он подключается только к сервисам, которым он доверяет.

Хотя это не WCF, вы могли бы попробовать использовать XMPP для запуска этой функциональности.Там есть статья о Информация об этом и других системах.Хотя в статье говорится, что XMPP нельзя использовать через HTTP, вы можете при использовании ЧУШЬ.

Доступны библиотеки .NET agsXMPP agsXMPP чтобы назвать одно из них.

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

Погуглите для "Дуплекс WCF".Я успешно использовал это, используя NetTcpBinding (на разных континентах), но я не уверен в BasicHttpBinding.

Однако для этого требуется, чтобы сервер перезвонил клиенту.Если серверу не разрешено это делать, опрос может быть вашим единственным вариантом...

ЕСЛИ сервер не может вызвать клиента (а обычно этого не должно быть), вы должны попросить клиента опросить сервер, как вы указали.поскольку у вас уже есть WCF foundation, просто добавьте для этого операцию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top