Внешние ключи помогают осуществить ссылочную целостность на уровне данных. Они также улучшают производительность, потому что они обычно индексируются по умолчанию.
Мне кажется, что вы уже знаете ответ: используйте длинный опрос. :) Итак, я думаю, единственное, что осталось объяснить, это как вы могли бы добиться этого с помощью WCF и наиболее эффективным способом.
sendTimeout = "00:05:00"
. TimeoutException
, которое вы можете перехватить, чтобы легко обнаружить, что это проблема или какое-то другое исключение. receiveTimeout = "00:05:00"
. Однако, если вы размещаете внутри ASP.NET, вам также необходимо настроить среду выполнения ASP.NET на более длительный тайм-аут, который выполняется с помощью
( примечание: измерения этого атрибута в секундах). Если вы просто настроили свой клиент для синхронного вызова службы, и клиент блокируется на 5 минут, ожидая ответа. , это не очень эффективное использование системных ресурсов. Вы можете поместить эти вызовы в фоновые потоки, но это ' s по-прежнему будет поглощать ресурс потока, пока вызов не завершен. Самый эффективный способ справиться с этим - использовать асинхронные операции.
Если вы создаете свои сервисные контракты вручную, я бы посоветовал проверить этот раздел в 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 Service Bus
. Вам нужно изучить WSDualHttpBinding
. WSDualHttpBinding предоставляет такая же поддержка протоколов веб-сервисов как WSHttpBinding, но для использования с дуплексные контракты. WSDualHttpBinding поддерживает только безопасность SOAP и требует надежного обмена сообщениями. Эта привязка требует, чтобы у клиента был общедоступный URI, обеспечивающий обратный вызов конечная точка для службы. Это предоставляется ClientBaseAddress. А двойная привязка раскрывает IP-адрес клиент к сервису. Клиент следует использовать безопасность, чтобы гарантировать, что подключается только к службам, которым доверяет.
Google по запросу " WCF duplex ". Я успешно использовал это, используя netTcpBinding (на разных континентах), но я не уверен в отношении basicHttpBinding.
Однако для этого требуется, чтобы сервер перезвонил клиенту. Если серверу это не разрешено, единственным вариантом может быть опрос ...
ЕСЛИ сервер не может вызвать клиента (а обычно и не должен), вы должны сделать так, чтобы клиент опрашивал сервер, как вы указали. поскольку у вас уже есть основа WCF, просто добавьте для этого операцию.
Хотя это и не WCF, вы можете попробовать использовать XMPP для реализации этой функции. Об этом и других системах есть статья в InfoQ . Хотя в статье говорится, что XMPP не может использоваться через HTTP, вы можете использовать BOSH .
Существуют библиотеки .NET agsXMPP , чтобы назвать их.
компания, в которой я работаю, начинает использовать его для отправки уведомлений об обновлениях в приложение для обновления частей пользовательского интерфейса.