Подтвердить что ты не робот

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

см. также "WCF для клика через брандмауэр"

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

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

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

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


Я ищу встроенный surport для " длинный опрос" / " Comet" и т.д.


Спасибо за самый информативный ответ от Drew Marsh о том, как реализовать длинный опрос в WCF. Однако я думал, что главной "точкой продажи" WCF было то, что вы могли бы делать такие вещи, просто настраивая каналы, которые будут использоваться в файле конфигурации. Например, я хочу, чтобы канал был логически двумя способами, но физически только входящими.

4b9b3361

Ответ 1

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


Основы:

  • Сначала определите, как долго вы хотите, чтобы каждый "длинный опрос" был. Для аргументации я собираюсь выбрать 5min таймаутов.
  • При привязке на стороне клиента измените sendTimeout="00:05:00".
  • Точно так же, как использование XmlHttpRequest (XHR) для длительного опроса, когда время ожидания действительно происходит, вам нужно будет его обнаружить и повторно отправить следующий запрос на опрос. Это довольно легко в WCF, потому что существует конкретное исключение, TimeoutException, которое вы можете поймать, чтобы легко обнаружить, что это проблема, другое исключение.
  • В зависимости от того, как вы размещаете свой сервис WCF, вам нужно будет настроить себя, чтобы разрешить обработку до 5 минут. С чистой точки зрения WCF вы должны убедиться, что вы установили receiveTimeout="00:05:00". Тем не менее, если вы размещаете внутри ASP.NET, вам также потребуется настроить время выполнения ASP.NET, чтобы иметь более высокий тайм-аут, который выполняется с помощью <httpRuntime executionTimeout="300" /> (note:). секунд для этого атрибута).

Быть эффективным в клиенте

Если вы просто настроили своего клиента для синхронного вызова службы и клиентских блоков на 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 с обработкой тех клиентов, которые фактически отправляются на событие. Все остальное должно просто заснуть, ожидая события. К счастью, тот же шаблон async, который мы использовали только на стороне клиента, также работает на стороне серверов. Однако теперь есть большая разница: теперь вы должны вернуть IAsyncResult (и, следовательно, WaitHandle) из метода BeginXXX который среда выполнения WCF будет ждать, пока ее не вызывают, прежде чем вызвать ваш метод EndXXX.

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

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

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

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

Ответ 2

Пока вы не используете WCF, вы можете попробовать использовать XMPP, чтобы получить эту функциональность. Там есть статья о InfoQ об этом и других системах. В статье говорится, что XMPP нельзя использовать через HTTP, вы можете использовать BOSH.

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

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

Ответ 3

Google для " WCF duplex". Я использовал это успешно, используя netTcpBinding (на континентах), но я не уверен над basicHttpBinding.

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

Ответ 4

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

Вы хотите посмотреть WSDualHttpBinding

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

Ответ 5

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