Визуальная обратная связь для службы WCF с самостоятельным размещением

У меня есть служба Windows, на которой размещена служба WCF на сервере. Я использую атрибут InstanceContextMode.PerSession. Услуги работают хорошо в соответствии с моими требованиями.

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


person swiftgp    schedule 18.09.2012    source источник


Ответы (4)


Я думаю, что самый простой ответ: этот. По сути, вы можете определить собственный прослушиватель трассировки для службы wcf. Вы можете изменить пример, чтобы получить желаемые результаты.

Реализация пользовательской трассировки выглядит следующим образом:

namespace WcfTrace.Trace
{
    public class WebTraceListener : TraceListener
    {
        public override void Write(string message)
        {
            //write you custom code here
            Debug.WriteLine(message);
        }

        public override void WriteLine(string message)
        {
            //write your custom code here
            Debug.WriteLine(message);
        }
    }
}

Конфигурация на хосте службы должна включать следующее:

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="WcfTrace.Trace.WebTraceListener,WcfTrace.Trace" />
    </sharedListeners>
  </system.diagnostics>

  <system.serviceModel>
    <diagnostics>
      <messageLogging
      logEntireMessage="true"
      logMalformedMessages="false"
      logMessagesAtServiceLevel="true"
      logMessagesAtTransportLevel="false"
      maxMessagesToLog="300000"
      maxSizeOfMessageToLog="200000"/>
    </diagnostics>
  </system.serviceModel>

Лично мне нравится эта идея, класс трассировщика, независимый от клиента (приложение со списком, которое вы упомянули), может получать информацию из этой пользовательской реализации трассировки, а также все, что может делать в будущем.

person danielQ    schedule 18.09.2012
comment
Быстрый вопрос, могу ли я иметь пользовательские сообщения для регистрации через этот механизм. Другими словами, могу ли я как-то в своем запросе службы WCF выдать собственное сообщение, которое может перехватить прослушиватель трассировки. - person swiftgp; 19.09.2012
comment
Нет, при таком подходе тег конфигурации messageLogging — это все, что вы можете настроить. - person danielQ; 19.09.2012

У службы нет пользовательского интерфейса, но у хоста он может быть.

Это просто хост консоли, но он отображает текст из службы.

Эти Console.WriteLine в службе отображаются на хосте.

namespace MagicEightBallServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**** Console Based WCF Host *****");

            using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
            {
                serviceHost.Open();
                Console.WriteLine("The service is running");
                Console.ReadLine();
            }

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
    public class MagicEightBallService : IEightBall, IDisposable
    {
        private DateTime serviceStartTime;
        public void Dispose()
        {

            Console.WriteLine("Eightball dispose ... " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());          
        }
        public MagicEightBallService()
        {
            serviceStartTime = DateTime.Now;
            Console.WriteLine("Eightball awaits your question " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
        }
        public string ObtainAnswerToQuestion(string userQuestion)
        {
            Console.WriteLine("Eightball ObtainsAnser " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
            return "maybe " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString() ;
        }
person paparazzo    schedule 18.09.2012
comment
Но мой хост — это служба Windows, поэтому я должен просто инициализировать форму статической функцией для записи и продолжать вызывать ее из службы WCF? - person swiftgp; 18.09.2012
comment
@ user1556110, нет. Это было бы неправильным способом сделать это. Службы Windows больше не могут напрямую взаимодействовать с рабочим столом из-за изоляции служб (по-моему, введенной в Vista). Поэтому запись в консоль из службы Windows вам не поможет. Короче говоря, вам нужно разработать пользовательский интерфейс, который может взаимодействовать с вашей службой Windows, используя какой-либо механизм IPC — сокеты, каналы, общую память и т. д. В своем ответе я привел пример того, как это сделать через WCF. - person Matt Davis; 18.09.2012
comment
Служба, как и служба Windows, не имеет пользовательского интерфейса. Этот простой трюк работает только при размещении службы в консоли. Ограничено, но легко. - person paparazzo; 18.09.2012

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

Отличительной чертой этой структуры является то, что она отделяет издателя, например, вашу службу WCF в вашей службе Windows, от любых подписчиков, например, вашего графического интерфейса. Издатель «публикует» события, представляющие интерес для службы Pub/Sub, которая всегда доступна. С точки зрения издателя не имеет значения, есть подписчики или нет. Служба Pub/Sub заботится о маршрутизации событий всем зарегистрированным подписчикам. Таким образом, ваша служба WCF в вашей службе Windows публикует события по мере их возникновения, ваш графический интерфейс будет подписываться/отписываться от службы публикации/подписки, когда она загружается/закрывается, а служба публикации/подписки будет уведомлять ваш графический интерфейс при возникновении событий.

Я использовал эту настройку в своем проекте, и она работает очень хорошо.

EDIT: я понимаю желание иметь собственный пользовательский интерфейс, отображающий события из службы WCF, размещенной в службе Windows. Другой вариант — использовать журнал приложений, доступный из собственного средства просмотра событий Windows (eventvwr.msc). Если этот подход приемлем, взгляните на мои инструкции здесь чтобы узнать, как настроить это из службы Windows.

person Matt Davis    schedule 18.09.2012

Используйте что-то вроде log4net для регистрации информации, которую вы хотите отобразить и которая представляет интересующую вас активность веб-службы. Используя log4net, вы можете отфильтровать, какой тип информации регистрируется, просто изменив файл конфигурации. Вы также можете изменить, где и как вы хотите получать информацию, зарегистрировавшись в файле конфигурации. Одним из приложений, которые вы можете настроить для log4net, является SysLogAppender. Это отправляет информацию журнала на удаленный SysLog Server (его можно развернуть с веб-службой как Что ж). Доступен ряд серверов SysLog, таких как Kiwi, которые будут обеспечивать прокручивающееся отображение журнала. событий и предоставляет фильтры и действия для определенных событий (например, отправить электронное письмо администратору при возникновении ошибки). Также доступны серверы SysLog с открытым исходным кодом. Это эффективно отделяет просмотр и обработку информации журнала от фактического ведения журнала.

person Kevin Junghans    schedule 18.09.2012