Как проверить доступность службы net.tcp WCF

Мой сервер WCF должен регулярно подниматься и опускаться, клиент иногда использует сервер, но если он не работает, клиент просто игнорирует его. Поэтому каждый раз, когда мне нужно использовать службы сервера, я проверяю состояние соединения и, если оно не открыто, открываю его. Проблема в том, что если я попытаюсь открыть, когда сервер не работает, возникнет задержка, которая повлияет на производительность. Мой вопрос в том, есть ли способ сделать что-то вроде myClient.CanOpen()? поэтому я бы знал, есть ли смысл открывать соединение с сервером.


person Pablo Retyk    schedule 19.05.2009    source источник
comment
Как именно это влияет на производительность? Не можете ли вы просто настроить клиент по умолчанию в отключенном режиме, пока он не подключится?   -  person Jonathan Parker    schedule 19.05.2009
comment
Когда я делаю myClient.Open(), если сервер не работает, есть тайм-аут, возможно, это не исключение, влияющее на производительность, я пересматриваю свой вопрос   -  person Pablo Retyk    schedule 19.05.2009


Ответы (5)


Существует реализация WS-Discovery, которая позволит вам прослушивать объявления вверх/вниз для вашего сервиса. Это также очень удобная форма разрешения адресов службы, поскольку она использует многоадресные сообщения UDP для поиска службы, а не настраивает один заданный адрес на клиенте. WS-Discovery для WCF

Также есть реализация, выполненная сотрудником Microsoft: Пример реализации WS-Discovery

.NET 4.0 будет включать это изначально. Вы можете прочитать о реализации .NET 4.0 в блоге Хесуса Родригеса. В нем есть отличная диаграмма, подробно описывающая ситуативное взаимодействие, происходящее в WS-Disco Использование WS-Discovery в WCF 4.0

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

Надеюсь это поможет.

person Anderson Imes    schedule 19.05.2009
comment
Прохладный! Спасибо, что расширили и объяснили мои мысли и показали, как это действительно может работать. - person Jon; 20.05.2009

Если вы выполняете синхронный вызов, ожидая тайм-аута сервера в приложении с пользовательским интерфейсом, вы должны делать это в другом потоке. Я сомневаюсь, что снижение производительности связано с накладными расходами на исключения. Связано ли ваше снижение производительности с нагрузкой на ЦП, доступностью графического интерфейса или временем настенных часов?

Вы можете выяснить, можете ли вы создать пользовательскую привязку по TCP, но с более быстрым временем ожидания.

Я предполагаю, что вы знаете, что «IsOneWay=true» быстрее, чем запрос-> ответ в вашем случае, потому что вы все равно не ожидаете ответа, но тогда вы не получаете подтверждение или возвращаемые значения. Вы также можете реализовать двустороннюю связь, которая не является запросом-> ответом.

person Tormod    schedule 19.05.2009

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

person Jon    schedule 19.05.2009
comment
WS-Открытие! Я напишу ответ, который включает это. - person Anderson Imes; 19.05.2009

Вот что я использую, и это работает как шарм. Кстати, класс ServiceController находится в пространстве имен System.ServiceProcess.

try
{
    ServiceController sc = new ServiceController("Service Name", "Computer's IP Address");
    Console.WriteLine("The service status is currently set to {0}",
        sc.Status.ToString());

    if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
        (sc.Status.Equals(ServiceControllerStatus.StopPending)))
    {
        Console.WriteLine("Service is Stopped, Ending the application...");
        Console.Read();
        EndApplication();
    }
    else
    {
        Console.WriteLine("Service is Started...");
    }
}
catch (Exception)
{
    Console.WriteLine("Error Occurred trying to access the Server service...");
    Console.Read();
    EndApplication();
}
person Dave_B    schedule 11.03.2014

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

Есть хороший пост в блоге WCF : доступность служб WCF, если вы заинтересованы в прочтении.

person Konstantinos    schedule 19.05.2009
comment
наличие клиентского метода, определяющего, где открыт сервис. Это то, что я ищу - person Pablo Retyk; 19.05.2009