Как автоматически восстановить дуплексный канал, если он выходит из строя? - PullRequest
13 голосов
/ 15 октября 2008

Я разрабатываю клиент-серверное приложение в .Net 3.5 с использованием WCF. По сути, долго работающий клиентский сервис (на нескольких машинах) устанавливает дуплексное соединение с сервером через netTcpBinding. Затем сервер использует контракт обратного вызова клиента для выполнения определенных операций по требованию, на которые клиент отвечает асинхронным образом (я думаю, что это довольно стандартная вещь). Я подкласс класса DuplexClientBase для обработки большей части связи.

К сожалению, когда что-то идет не так с обеих сторон (например, сбой сети, неожиданное исключение и т. Д.), Канал выходит из строя / прерывается и все последующие операции завершаются неудачно. Я обошел это ограничение в недуплексных каналах, создав класс RecoveringClientBase, который автоматически обнаруживает ошибку клиента и повторяет операцию.

Итак, мой вопрос: существует ли установленный способ определения, когда дуплексный канал вышел из строя? Где я должен проверить это, на сервере или на клиенте? В противном случае, какие варианты у меня есть, чтобы гарантировать, что соединение будет восстановлено?

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

Ответы [ 4 ]

3 голосов
/ 10 января 2009

Я испытывал слабость в длительных сессиях (минуты-часы). Я не могу быть уверен, что это WCF, я почти уверен, что это сетевой уровень.

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

Я думаю о размещении конечной точки службы на клиенте для операций, которые в настоящее время являются частью контракта обратного вызова. Клиент связывается с сервером с информацией о конечной точке, сервер может хранить их где-то (сохраненные или где угодно). Когда серверу необходимо связаться с клиентом, он открывает соединение с клиентом с помощью сохраненных сведений о конечной точке. По сути, превращение дуплексного соединения в 2 клиент-серверных соединения.

Не отвечает на ваш вопрос, но я чувствую вашу боль.

1 голос
/ 15 октября 2008

У Николаса Аллена из команды WCF есть предложения для этого:

http://blogs.msdn.com/drnick/archive/2007/11/05/custom-transport-retry-logic.aspx

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

0 голосов
/ 18 января 2011

Я думаю, что вы действительно должны слушать о сбойном событии. Вы можете прослушивать его на обоих концах, на стороне клиента, я думаю, что вы уже обрабатываете, конец сервера - OperationContext.Current.Channel.events.

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

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

По сути, единственный способ восстановления из неисправного / закрытого канала - это замена его новым, однако наиболее важной частью является то, что вы действительно должны обнаружить отключение по ВРЕМЕНИ, я обнаружил, что активация надежного сеанса будет вовремя вызывать сбойное событие большая часть дела. В качестве альтернативы, вы можете отправлять сообщения пульса на обоих концах, чтобы "проверить" канал неисправен.

0 голосов
/ 07 января 2009

У меня были похожие проблемы, и мне кажется, что эти длительные вызовы более или менее не поддерживаются.

WCF, похоже, предназначен для коротких звонков. Службы, которые вызываются, делают небольшие вещи и заканчивают работу.

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

...