【问题标题】:Visual feedback for a self-hosting WCF service自托管 WCF 服务的视觉反馈
【发布时间】:2012-09-18 15:31:08
【问题描述】:

我有一个在服务器上托管 WCF 服务的 Windows 服务。我正在使用InstanceContextMode.PerSession 属性。根据我的要求,服务运行良好。

我现在想为 WCF 服务实现视觉反馈,例如记录器,最好在 Windows 窗体的列表框中。我希望所有客户的所有呼叫和后续操作都记录在此表单中。我读到有一个服务的用户界面不是一个好主意。有人可以指出我以线程安全的方式实现这一目标的方向吗?

【问题讨论】:

    标签: .net wcf windows-services self-hosting


    【解决方案1】:

    我认为最简单的答案是this one。 基本上,您可以做的是为您的 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>
    

    我个人喜欢这个想法,独立于客户端的跟踪器类(您提到的带有列表框的应用程序)可以使用来自此自定义跟踪实现的信息,以及将来可以做的任何其他事情。

    【讨论】:

    • 快速提问,我可以通过这种机制记录自定义消息吗?换句话说,我是否可以在我的 WCF 服务请求中以某种方式发出跟踪侦听器可以捕获的自定义消息。
    • 不,用这种方法messageLogging 配置标签就是你得到的所有自定义。
    【解决方案2】:

    服务没有用户界面,但主机可以。

    这只是一个控制台主机,但它显示来自服务的文本。

    Service 中的那些 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() ;
            }
    

    【讨论】:

    • 但是我的主机是windows服务,所以我应该用静态函数初始化一个表单来编写并继续从WCF服务调用它吗?
    • @user1556110,没有。那将是错误的做法。由于服务隔离(我相信在 Vista 中引入),Windows 服务不能再直接与桌面交互。因此,从您的 Windows 服务写入控制台对您没有帮助。简而言之,您需要开发一个可以使用某种 IPC 机制(套接字、管道、共享内存等)与您的 Windows 服务进行通信的 UI。我在回答中提供了一个如何通过 WCF 执行此操作的示例。
    • Windows 服务中的服务没有 UI。这个简单的技巧只有在控制台中托管服务时才有效。有限但容易。
    【解决方案3】:

    您所说的本质上是让您的 Windows 服务中的 WCF 服务在发生“有趣”的事情时向 UI 前端提供事件通知。幸运的是,有一个Publish-Subscribe FrameworkJuval Lowy 开发,Programming WCF Services 的作者。详细描述在this excellent MSDN article,源代码在Lowy's website免费提供。

    这个框架的巧妙之处在于它将发布者(例如您的 Windows 服务中的 WCF 服务)与任何订阅者(例如您的 GUI)分离。发布者“发布”Pub/Sub 服务感兴趣的事件,该服务始终可用。从发布者的角度来看,有没有订阅者并不重要。 Pub/Sub 服务负责将事件路由到所有注册的订阅者。这样,您的 Windows 服务中的 WCF 服务会在事件发生时发布事件,您的 GUI 将在加载/退出时订阅/取消订阅 Pub/Sub 服务,并且 Pub/Sub 服务将在事件发生时通知您的 GUI。

    我在我的项目中使用了这个设置,效果非常好。

    编辑: 我理解希望拥有自己的 UI 来显示来自 Windows 服务托管的 WCF 服务的事件。另一种选择是利用可从 Windows 本机事件查看器 (eventvwr.msc) 访问的应用程序日志。如果这种方法可以接受,请查看我的说明 here,了解如何从 Windows 服务进行设置。

    【讨论】:

      【解决方案4】:

      使用log4net 之类的内容来记录您要显示的代表感兴趣的网络服务活动的信息。通过使用 log4net,您只需更改配置文件即可过滤记录的信息类型。您还可以通过登录配置文件来更改信息的位置和方式。您可以为 log4net 配置的附加程序之一是 SysLogAppender。这会将日志信息发送到远程SysLog Server(它也可以与 Web 服务一起部署)。有许多可用的 SysLog 服务器,例如 Kiwi,它将提供日志事件的滚动显示,并提供对某些事件的过滤器和操作(例如:发生错误时向管理员发送电子邮件)。还有open source SysLog Severs 可用。这有效地将日志信息的查看和处理与实际日志记录分离。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-07
        • 1970-01-01
        • 2013-06-09
        • 1970-01-01
        相关资源
        最近更新 更多