启用 SignalR 跟踪

作者 Tom FitzMacken

警告

本文档不适用于最新版本的 SignalR。 查看 ASP.NET Core SignalR

本文档介绍如何为 SignalR 服务器和客户端启用和配置跟踪。 跟踪使你能够查看有关 SignalR 应用程序中事件的诊断信息。

本主题最初由帕特里克·弗莱彻撰写。

本教程中使用的软件版本

问题和评论

请留下反馈,说明你对本教程的喜爱程度,以及我们可以在页面底部的评论中改进的内容。 如果你有与本教程不直接相关的问题,可以将其发布到 ASP.NET SignalR 论坛StackOverflow.com

启用跟踪后,SignalR 应用程序会为事件创建日志条目。 可以从客户端和服务器记录事件。 服务器上的跟踪记录连接、扩展提供程序和消息总线事件。 客户端上的跟踪记录连接事件。 在 SignalR 2.1 及更高版本中,客户端上的跟踪记录中心调用消息的完整内容。

目录

在服务器上启用跟踪

在应用程序的配置文件中的服务器上启用跟踪 (App.config或Web.config,具体取决于 project 的类型。) 指定要记录的事件类别。 在配置文件中,还可以指定是使用 TraceListener 的实现将事件记录到文本文件、Windows 事件日志还是自定义日志中。

服务器事件类别包括以下类型的消息:

消息
SignalR.SqlMessageBus SQL 消息总线扩展提供程序设置、数据库操作、错误和超时事件
SignalR.ServiceBusMessageBus 服务总线扩展提供程序主题创建和订阅、错误和消息传送事件
SignalR.RedisMessageBus Redis 扩展提供程序连接、断开连接和错误事件
SignalR.ScaleoutMessageBus 横向扩展消息传送事件
SignalR.Transports.WebSocketTransport WebSocket 传输连接、断开连接、消息传送和错误事件
SignalR.Transports.ServerSentEventsTransport ServerSentEvents 传输连接、断开连接、消息传递和错误事件
SignalR.Transports.ForeverFrameTransport ForeverFrame 传输连接、断开连接、消息传送和错误事件
SignalR.Transports.LongPollingTransport LongPolling 传输连接、断开连接、消息传送和错误事件
SignalR.Transports.TransportHeartBeat 传输连接、断开连接和 keepalive 事件
SignalR.ReflectedHubDescriptorProvider 中心发现事件

将服务器事件记录到文本文件中

以下代码演示如何为每个类别的事件启用跟踪。 此示例将应用程序配置为将事件记录到文本文件中。

用于启用跟踪的 XML 服务器代码

<system.diagnostics>
    <sources> 
      <source name="SignalR.SqlMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ServiceBusMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.RedisMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ScaleoutMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.Transports.WebSocketTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>     
      <source name="SignalR.Transports.ServerSentEventsTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.ForeverFrameTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.LongPollingTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.TransportHeartBeat">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.ReflectedHubDescriptorProvider">
        <listeners>
          <add name="SignalR-Init" />
        </listeners>
      </source>
    </sources>
    <!-- Sets the trace verbosity level -->
    <switches>
      <add name="SignalRSwitch" value="Verbose" />
    </switches>
    <!-- Specifies the trace writer for output -->
    <sharedListeners>
      <!-- Listener for transport events -->
      <add name="SignalR-Transports" type="System.Diagnostics.TextWriterTraceListener" initializeData="transports.log.txt" />
      <!-- Listener for scaleout provider events -->
      <add name="SignalR-Bus" type="System.Diagnostics.TextWriterTraceListener" initializeData="bus.log.txt" />
      <!-- Listener for hub discovery events -->
      <add name="SignalR-Init" type="System.Diagnostics.TextWriterTraceListener" initializeData="init.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

在上面的代码中 SignalRSwitch , 条目指定用于发送到指定日志的事件的 TraceLevel 。 在这种情况下,它设置为 Verbose ,这意味着将记录所有调试和跟踪消息。

以下输出显示了使用上述配置文件的应用程序的 文件中的条目 transports.log.txt 。 它显示新连接、已删除的连接和传输检测信号事件。

SignalR.Transports.TransportHeartBeat Information: 0 : Connection 9aa62c9b-09b3-416c-b367-06520e24f780 is New.
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.WebSocketTransport Information: 0 : Abort(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.TransportHeartBeat Information: 0 : Removing connection 9aa62c9b-09b3-416c-b367-06520e24f780
SignalR.Transports.WebSocketTransport Information: 0 : End(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(9aa62c9b-09b3-416c-b367-06520e24f780)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (9aa62c9b-09b3-416c-b367-06520e24f780)

将服务器事件记录到事件日志中

若要将事件记录到事件日志而不是文本文件中,请更改节点中 sharedListeners 条目的值。 以下代码演示如何将服务器事件记录到事件日志中:

用于将事件记录到事件日志的 XML 服务器代码

<sharedListeners>
  <!-- Listener for transport events -->
  <add name="SignalR-Transports" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRTransportLog" />
  <!-- Listener for scaleout provider events -->
  <add name="SignalR-Bus" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRScaleoutLog" />
  <!-- Listener for hub discovery events -->
  <add name="SignalR-Init" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRInitLog" />
</sharedListeners>

事件记录在应用程序日志中,并通过事件查看器提供,如下所示:

显示 SignalR 日志的事件查看器

注意

使用事件日志时,将 TraceLevel 设置为 Error ,使消息数保持可管理。

在 .NET 客户端 (Windows 桌面应用中启用跟踪)

.NET 客户端可以使用 TextWriter 的实现将事件记录到控制台、文本文件或自定义日志中。

若要在 .NET 客户端中启用日志记录,请将连接的 TraceLevel 属性设置为 TraceLevels 值,将 TraceWriter 属性设置为有效的 TextWriter 实例。

将桌面客户端事件记录到控制台

以下 C# 代码演示如何将 .NET 客户端中的事件记录到控制台:

var hubConnection = new HubConnection("http://www.contoso.com/");
hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = Console.Out;
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();

将桌面客户端事件记录到文本文件

以下 C# 代码演示如何将 .NET 客户端中的事件记录到文本文件中:

var hubConnection = new HubConnection("http://www.contoso.com/");
var writer = new StreamWriter("ClientLog.txt");
writer.AutoFlush = true;
hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = writer;
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();

以下输出显示了使用上述配置文件的应用程序的 文件中的条目 ClientLog.txt 。 它显示连接到服务器的客户端,以及中心调用名为 的 addMessage客户端方法:

19:41:39.9103763 - null - ChangeState(Disconnected, Connecting)
19:41:40.3750726 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS Connecting to: ws://localhost:8080/signalr/signalr/connect?transport=webSockets&clientProtocol=1.4&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAh8Lp 
KH5%2FDkCQeR4ALAwR%2BAAAAAACAAAAAAADZgAAwAAAABAAAADHpCa7wm%2FbOhjluf%2Fm9GA9AAAAAASAAACgAAAAEA 
AAAEqRfJihLExRI6tZy7lWRwYoAAAApotSsJXW0OiwEgiUUi0pzhK6oKbz%2BkMeVbezuEDQLnJecM9otFe9PRQAAAAuHK
BlOnPmXt%2FhXV%2Felr1QvC156Q%3D%3D&connectionData=[{"Name":"MyHub"}]
19:41:40.4442923 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS: OnMessage({"C":"d-5196BF5C-A,0|B,0|C,1|D,0","S":1,"M":[]})
19:41:40.4874324 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - ChangeState(Connecting, Connected)
19:41:47.4511770 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS: OnMessage({"C":"d-5196BF5C-A,1|B,0|C,1|D,0","M":[{"H":"MyHub","M":"addMessage","A":["User One","Hello!"]}]})
19:41:47.4576968 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS: OnMessage({"I":"0"})
19:41:50.3959119 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS: OnMessage({})
19:41:50.8928084 - dd61fd48-d796-4518-b36b-ec1dcb970d72 - WS: OnMessage({"C":"d-5196BF5C-A,2|B,0|C,1|D,0","M":[{"H":"MyHub","M":"addMessage","A":["User Two","Hello!"]}]})

在 Windows Phone 8 客户端中启用跟踪

适用于 Windows Phone 应用的 SignalR 应用程序使用与桌面应用相同的 .NET 客户端,但 Console.Out 和使用 StreamWriter 写入文件不可用。 相反,你需要创建用于跟踪的 TextWriter 的自定义实现。

将Windows Phone客户端事件记录到 UI

SignalR 代码库包含一个Windows Phone示例,该示例使用名为 的TextBlockWriter自定义 TextWriter 实现将跟踪输出写入 TextBlock。 可以在 samples/Microsoft.AspNet.SignalR.Client.WP8.Samples 项目中找到此类。 创建 实例 TextBlockWriter时,传入当前 SynchronizationContextStackPanel ,它将在其中创建用于跟踪输出的 TextBlock

Connection = new HubConnection(ServerURI);
var writer = new TextBlockWriter(SynchronizationContext.Current, StackPanelConsole);
Connection.TraceWriter = writer;
Connection.TraceLevel = TraceLevels.All;

然后,跟踪输出将写入传入的 StackPanel 中创建的新 TextBlock

显示Windows Phone示例的屏幕截图,其中显示输出。

将Windows Phone客户端事件记录到调试控制台

若要将输出发送到调试控制台而不是 UI,请创建写入调试窗口的 TextWriter 实现,并将其分配给连接的 TraceWriter 属性:

Connection = new HubConnection(ServerURI);
var writer = new DebugTextWriter();
Connection.TraceWriter = writer;
Connection.TraceLevel = TraceLevels.All;

...

private class DebugTextWriter : TextWriter
{
    private StringBuilder buffer;

    public DebugTextWriter()
    {
        buffer = new StringBuilder();
    }

    public override void Write(char value)
    {
        switch (value)
        {
            case '\n':
                return;
            case '\r':
                Debug.WriteLine(buffer.ToString());
                buffer.Clear();
                return;
            default:
                buffer.Append(value);
                break;
        }
    }
            
    public override void Write(string value)
    {
        Debug.WriteLine(value);
                
    }
    #region implemented abstract members of TextWriter
    public override Encoding Encoding
    {
        get { throw new NotImplementedException(); }
    }
    #endregion
}

然后,跟踪信息将写入 Visual Studio 中的调试窗口:

显示“输出”对话框的屏幕截图。调试位于“显示输出”字段中。

在 JavaScript 客户端中启用跟踪

若要对连接启用客户端日志记录,请在调用 start 方法建立连接之前,在连接对象上设置 logging 属性。

用于使用生成的代理 (对浏览器控制台启用跟踪的客户端 JavaScript 代码)

$.connection.hub.logging = true;
$.connection.hub.start();

客户端 JavaScript 代码,用于在不使用生成的代理的情况下 (对浏览器控制台启用跟踪)

var connection = $.hubConnection();
connection.logging = true;
connection.start();

启用跟踪后,JavaScript 客户端会将事件记录到浏览器控制台。 若要访问浏览器控制台,请参阅 监视传输

以下屏幕截图显示了启用了跟踪的 SignalR JavaScript 客户端。 它在浏览器控制台中显示连接和中心调用事件:

浏览器控制台中的 SignalR 跟踪事件