WCF - Клиентский обратный вызов по сравнению с опросом для “сохраняет список подписчиков”

Я не знаю о Подрывной деятельности, в частности, но я полагаю, что каждый проект, даже один с единственным разработчиком, должен использовать управление версиями. Я посмотрел бы на несколько опций (CVS, SubVersion, мерзавец, Базар, Visual SourceSafe) и видел бы, какой (s) встречают требования Вашей команды лучшее.

7
задан David Basarab 15 December 2009 в 17:32
поделиться

4 ответа

I had a similar situation using WCF and callbacks. I did not want to use polling, but I was using a "reilable" protocol, so if a client died, then it would hang the server until it timed out and crashed.

I do not know if this is the most correct or elegant solution, but what I did was create a class in the service to represent the client proxy. Each instance of this class contained a reference to the client proxy, and would execute the callback function whenever the server set the "message" property of the class. By doing this, when a client disconnected, the individual wrapper class would get the timeout excetpion, and remove itself from the server's list of listeners, but the service would not have to wait for it. This doesn't actually answer your question about determining if the client is alive, but it is another way of structuring the service to addrss the issue. If you needed to know when a client died, you would be able to pick up when the client wrapper removed itself from the listener list.

0
ответ дан 7 December 2019 в 12:21
поделиться

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

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

Поместите этот атрибут на сервер и клиент класса реализации сервера WCF

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WCFServerClass

ConcurrencyMode.Multiple выполняет каждый процесс вызова в своем собственном потоке, который должен помочь вам с блокировкой сервера, когда клиент умирает, пока не истечет время ожидания.

Я также убедился, что использовал пул потоков на стороне клиента, чтобы убедиться, что на стороне клиента нет проблем с потоками

0
ответ дан 7 December 2019 в 12:21
поделиться

Большинство изменений в состоянии подключения можно обнаружить с помощью Closed , Closing и Неисправные события для ICommunicationObject . Вы можете подключить их одновременно с настройкой обратного вызова. Это определенно лучше, чем опрос.

IIRC, событие Faailed будет срабатывать только после того, как вы действительно попытаетесь использовать обратный вызов (безуспешно). Поэтому, если Клиент просто исчезнет - например, при аппаратной перезагрузке или отключении питания - вы не получите уведомление сразу. Но нужно ли вам быть? И если да, то почему?

Обратный вызов WCF может завершиться ошибкой в ​​любой момент, и вам всегда нужно помнить об этом. Даже если и клиент, и сервер в порядке, вы все равно можете получить неисправный канал из-за исключения или сбоя сети. Или, может быть, клиент отключился где-то между вашим последним опросом и вашей текущей операцией. Дело в том, что до тех пор, пока вы кодируете свои операции обратного вызова в целях защиты (что в любом случае является хорошей практикой), то для большинства проектов обычно достаточно перехвата указанных выше событий. Если по какой-либо причине возникает ошибка, включая отказ клиента от ответа, произойдет событие Faailed и запустит ваш код очистки.

Это то, что я бы назвал пассивным / ленивым подходом и требует меньше кодирования и сетевой болтовни, чем методы опроса или поддержания активности.

до тех пор, пока вы кодируете свои операции обратного вызова в целях защиты (что в любом случае является хорошей практикой), то для большинства проектов обычно достаточно перехвата указанных выше событий. Если по какой-либо причине возникает ошибка, включая отказ клиента от ответа, запускается событие Faailed и запускается ваш код очистки.

Это то, что я бы назвал пассивным / ленивым подходом и требует меньше кодирования и сетевой болтовни, чем методы опроса или поддержания активности.

до тех пор, пока вы кодируете свои операции обратного вызова в целях защиты (что в любом случае является хорошей практикой), то для большинства проектов обычно достаточно перехвата указанных выше событий. Если по какой-либо причине возникает ошибка, включая отказ клиента от ответа, произойдет событие Faailed и запустит ваш код очистки.

Это то, что я бы назвал пассивным / ленивым подходом и требует меньше кодирования и сетевой болтовни, чем методы опроса или проверки активности.

3
ответ дан 7 December 2019 в 12:21
поделиться

Если вы включаете надежные сеансы, WCF внутренне поддерживает механизм контроля активности. Он регулярно проверяет с помощью скрытых тестовых сообщений инфраструктуры, есть ли еще другой конец. На временной интервал этих проверок можно влиять с помощью свойства ReliableSession.InactivityTimeout. Если вы установите для свойства, скажем, 20 секунд, то событие ICommunicationObject.Faaled будет вызвано примерно через 20–30 (максимум) секунд после того, как на другой стороне произошел сбой службы.

Если вы хотите быть уверены, что клиентские приложения всегда остаются «автоматически подключаемыми», даже после временных сбоев службы, вы можете использовать рабочий поток (из пула потоков), который неоднократно пытается создать новый экземпляр прокси на на стороне клиента и вызывает операцию, инициирующую сеанс, после того, как там возникло событие Faaled.

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

Используя первый или второй подход, вы можете реализовать архитектуру служебной шины (шаблон посредника), гарантирующую, что все экземпляры клиентского приложения постоянно готовы к приему «спонтанных» служебных сообщений всякий раз, когда служба работает.

Конечно,это работает, только если надежный сеанс «как таковой» настроен правильно с самого начала (с использованием привязки, поддерживающей сеанс, и применения свойств ServiceContractAttribute.SessionMode, ServiceBehaviorAttribute.InstanceContextMode, OperationContractAttribute.IsInitiating и OperationContractAttribute.IsTerminating осмысленными способами).

2
ответ дан 7 December 2019 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: