Решение WCF, необходимое для класса обслуживания

У меня есть класс, который вызывает некоторые события и выполняет операции. Например

class MyService
{
    EventHandler MessageSent;
    EventHandler StatusReceived;

    public void StartService(Serviceconfig configObject)
    {
         //Intialize serial port with OnSerialPortReceived event handler.

    }

    public void GetStatusForMessage(string messageID)
    {
    }

    public void OnSerialPortReceived(string data)
    {
        if(data=="123")
              MessageSent(this,null);
        if(data=="456")
              StatusSent(this,null);
    }
}

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

Я нашел эту статью http://msdn.microsoft.com/en-us/magazine/cc163537.aspx. При таком подходе мой сервис станет клиентом-издателем, а приложение-монитор станет клиентским приложением-подписчиком. Но клиент должен совершать вызовы класса обслуживания. Поэтому мое клиентское приложение должно поддерживать оба обратных вызова, а также иметь возможность вызывать методы службы. Как я могу добиться этого с помощью WCF? Обратите внимание, что класс службы, который отслеживает события, является единственным экземпляром и инициализируется при запуске приложения.

Надеюсь, я получу решения для этого. Пожалуйста, дайте мне знать для получения дополнительных разъяснений.


person Sudhakar B    schedule 16.05.2012    source источник


Ответы (2)


Не пытайтесь сделать свой сервис классом сервиса WCF. Сделайте его синглтоном и попросите WCF поговорить с ним.

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

Обратите внимание, что вам придется поддерживать сеансы с обеих сторон, поэтому приложение мониторинга и служба должны будут запускать друг другу что-то чаще, чем настроенное значение receiveTimeout (по умолчанию 10 минут), но это может быть просто метод "ping" для использования в качестве проверки активности

Я написал в блоге о двусторонней связи некоторое время назад, если это поможет

person Richard Blewett    schedule 16.05.2012
comment
Привет, я видел твой блог, это хороший блог. Если я сделаю это как синглтон, объект будет создан, когда клиент будет запрошен, верно? но в моем случае объект уже создан. Поэтому мне нужно создать службу WCF, которая будет с ней разговаривать. Итак, как одноэлементный объект WCF может взаимодействовать с моим уже созданным служебным объектом. - person Sudhakar B; 16.05.2012
comment
Извините - не синглтон WCF, а синглтон в смысле шаблонов проектирования - вы можете создать его при запуске несколькими способами - помните, я сказал не делать ваш сервис сервисом WCF. На самом деле синглтон WCF создается, когда ServiceHost открывается не по первому запросу, но я бы не стал привязывать ваш класс обслуживания к WCF - person Richard Blewett; 16.05.2012
comment
Ой! OK. Даже я также не хочу привязывать свой класс обслуживания WCF к моему классу обслуживания. Теперь моя проблема заключается в том, как взаимодействовать с моим объектом класса обслуживания WCF и моим классом обслуживания. Нужно иметь глобальный объект моего класса обслуживания, чтобы я мог получить к нему доступ в WCF singleton? (не думаю, что это хорошая идея). - person Sudhakar B; 16.05.2012
comment
Класс обслуживания WCF должен знать класс обслуживания даже через абстракцию (что упростит модульное тестирование). Одноэлементный шаблон в .NET хорошо документирован msdn.microsoft.com/en-us. /library/ee816881.aspx например. в этой статье вы хотите использовать статическую модель инициализации и убедиться, что у вас есть тип класса обслуживания в вашем коде запуска. Это приведет к запуску статического инициализатора и созданию вашего объекта при запуске. - person Richard Blewett; 16.05.2012
comment
Спасибо. Эта ссылка правильная? Это приводит меня к ‹protocolMapping›. На самом деле в program.cs я запущу свою службу приложений, а также запущу однотонную службу WCF. Итак, теперь, как мне получить доступ к объекту в program.cs в однотонной службе WCF для взаимодействия (вот где я действительно застрял ). - person Sudhakar B; 17.05.2012
comment
ах, извините - должно быть, не удалось скопировать ссылку и в итоге оказалась та, что была в буфере обмена - это правильная ссылка msdn.microsoft.com/en-us/library/ff650316.aspx. Вы получаете доступ к синглтону через статический помощник (как в статье, связанной) - person Richard Blewett; 17.05.2012
comment
Привет, спасибо за ссылку. Я разработал простое приложение с использованием WCF, которое удовлетворяет моим требованиям. Как вы сказали, я создал одноэлементный сервисный класс WCF и одноэлементный сервисный объект. Я устанавливаю ссылку службы приложений на объект одноэлементной службы WCF во время инициализации. Я думаю, это правильный метод? вы предлагаете какой-либо другой метод? Теперь предположим, что если мы реализуем объект службы WCF для каждого сеанса, то как лучше всего получить доступ к моему объекту службы приложения внутри объекта WCF для каждого сеанса? Просто имея статический член, который возвращает экземпляр? - person Sudhakar B; 17.05.2012
comment
Модель создания экземпляров в WCF на самом деле не имеет никакого значения в отношении вашего синглтона — просто используйте статический метод доступа, как в статье. Однако с одноэлементной службой WCF имейте в виду, что вы будете обрабатывать только один запрос за раз, если вы не измените ConcurrencyMode на Multiple. Если вы сделаете это, вы будете нести ответственность за обеспечение безопасности потока кода. - person Richard Blewett; 17.05.2012

  1. Сделайте свой «сервис» сервисом Widnows, а не консольным приложением.
  2. Вы можете без проблем сделать свой класс MyService службой WCF. Но вы также можете создать другой класс для размещения вашего контракта на обслуживание и просто общаться с реализацией службы Windows.
  3. Нет никакой связи между временем активации службы Windows и первым запросом WCF (это не IIS, это собственная служба WCF, вы запускаете ее, когда хотите).
  4. Вот ссылка на руководство по самостоятельному размещению службы WCF
  5. Установите службу Windows на свой компьютер с опцией автозапуска.
person Grzegorz W    schedule 18.05.2012