Есть консольное приложение, в котором запускаются некие WCF-службы
Надо определить адреса (в общем случае порты от localhost) запущенных на текущий момент времени служб
Как это сделать?
И можно ли это сделать?
Может, есть место, где все они сами по себе регистрируются?
PS. варианты парсить config или собрать все запускаемые службы в список при открытии просьба не предлагать
Спасибо
Re: Найти адреса запущенных WCF-сервисов в приложении
Если я правильно понял то ,что вы хотите, то это выглядит так:
Нужно уметь получать в runtime список всех хостящихся в процессе WCF-сервисов, причем мы не имеем возможности контролировать объявление и инициализацию этих сервисов (навешивать атрибуты, менять конфигурацию, использовать свой ServiceHost, ...). Иными словами — код запускающий сервисы для нас "черный ящик", и мы можем только обращаться к инфраструктeре WCF
.
Честно говоря, я не знаю простого и "законного" (т.е. через какое-то публичное API инфраструктуры WCF) способа получить общую информацию обо всех экземпляров сервисов, запущенных в текущем процессе.
Т.е. из того, что я знаю — каждый экземпляр сервиса (ну и всей обвязки вокруг: ServiceHost, всякие Dispatchers, ...) — независим от остальных. Т.е. никакого внутреннего реестра запущенных сервисов нет (ну или не понятно как до него добраться).
Из того, что мало-мальски можно предложить — это "инъекции" behaviours. Например, если написать вот такой
Endpoint behavior
public class EndpointSpyBehavior : IEndpointBehavior
{
public static List<Uri> Endpoints = new List<Uri>();
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
EndpointSpyBehavior.Endpoints.Add(endpoint.Address.Uri);
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
А к нему
BehaviorExtensionElement
public class EndpointSpyBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(EndpointSpyBehavior); }
}
protected override object CreateBehavior()
{
return new EndpointSpyBehavior();
}
}
static void Main(string[] args)
{
var serviceHost = new ServiceHost(typeof(Service), new Uri("http://localhost:13056"));
var serviceHost2 = new ServiceHost(typeof(Service), new Uri("http://localhost:15401"));
serviceHost.Open();
serviceHost2.Open();
EndpointSpyBehavior.Endpoints.ForEach(u => Console.WriteLine(u));
Console.ReadLine();
serviceHost.Close();
serviceHost2.Close();
}
НО!!!
Это работает только если нигде никакой endpoint не ссылается ни на какой behavior configuration (тогда берется дефолтовая). Т.е. если поменять конфиг на такой:
App.config с явной ссылкой на behavior configuration
Или аналогичное сделать в коде (т.е. указать behavior configuration явно там) — всё, behavior configuration по умолчанию (он без имени) подхватываться не будет.
Теоретически можно добавить еще ServiceBehavior (примерно так же делается) и в нем смотреть — если для endpoint наш behavior не добавлен, то добавить.
Но это тоже полумеры (ломается так же — у сервиса явно указан свой behavior
Re: Найти адреса запущенных WCF-сервисов в приложении
В добавление к предыдущему моему ответу: может всё же есть какие-то вещи, на которые вы можете влиять: указывать behavior для всех сервисов (и в коде это нельзя перекрывать) или запуск-таки осуществляет какой-то ваш код (хотя вы писали, что это не вариант, но вдруг есть лазейка), в конце концов может вы можете выставить какие-то требования к конфигу...
Без такого, боюсь, останется только что-то из "хакерского" набора (всё далее — это предположения, ничем подобным я не занимался):
— попробовать настроить запись в логи (там есть запись в XML), подсунуть свой форматер и попробовать ловить события с нужным типом.
— поймать события создания инстансов объектов (например, DispatchRuntime) и попробовать порыть от них.
— просто порыться в исходника внутренних объектов (того же DispatchRuntime) — вдруг-таки есть какой-то внутренний shared объект, от которого можно пробежаться по экземплярам инфраструктуры
— ну и подобное ...
Re[2]: Найти адреса запущенных WCF-сервисов в приложении
Здравствуйте, Михаил Романов, Вы писали:
МР>Если я правильно понял то ,что вы хотите, то это выглядит так:
да, Михаил, спасибо, это выглядит именно так
но у меня нет возможности ориентироваться на config — часть служб конфигурируется программно
там каша полная, доступиться туда пока нельзя, потому и спрашиваю такой идиотский вопрос
Re[2]: Найти адреса запущенных WCF-сервисов в приложении
Здравствуйте, Михаил Романов, Вы писали:
МР>В добавление к предыдущему моему ответу: может всё же есть какие-то вещи, на которые вы можете влиять: указывать behavior для всех сервисов (и в коде это нельзя перекрывать) или запуск-таки осуществляет какой-то ваш код (хотя вы писали, что это не вариант, но вдруг есть лазейка), в конце концов может вы можете выставить какие-то требования к конфигу...
увы, нет
можно только жутко наговнокодить, чего хочется избежать
МР>Без такого, боюсь, останется только что-то из "хакерского" набора (всё далее — это предположения, ничем подобным я не занимался): МР>- попробовать настроить запись в логи (там есть запись в XML), подсунуть свой форматер и попробовать ловить события с нужным типом.
логи тоже надо как-то службе разрешить
МР>- поймать события создания инстансов объектов (например, DispatchRuntime) и попробовать порыть от них. МР>- просто порыться в исходника внутренних объектов (того же DispatchRuntime) — вдруг-таки есть какой-то внутренний shared объект, от которого можно пробежаться по экземплярам инфраструктуры
исходники я копал, но ничего не нашел — все совершенно независимо
пробовал слушателей обнаруживать — обнаруживаются, но большой кучей, на уровне системы, со службами их не связать
есть вариант связать их с процессом и покопать оттуда
Discovery пробовал, но он по голому IP вроде как не может
Re: Найти адреса запущенных WCF-сервисов в приложении
Здравствуйте, mDmitriy, Вы писали:
D>Есть консольное приложение, в котором запускаются некие WCF-службы D>Надо определить адреса (в общем случае порты от localhost) запущенных на текущий момент времени служб D>Как это сделать? D>И можно ли это сделать? D>Может, есть место, где все они сами по себе регистрируются?
Можно попробовать через ETW.
Там есть разные события (например, для net.tcp вот из такого можно достать порт).
Здравствуйте, igorl_r, Вы писали:
_>Можно через WMI. Но для этого нужно включить поддержку в конфиге.
Похоже, это как раз то, что искал mDmitriy — добавить одну настройку в конфиг уж точно реализуемо (можно даже проверять это и если что, править в приложении-хосте).