启用 SignalR 跟踪
警告
本文档不适用于最新版本的 SignalR。 查看 ASP.NET Core SignalR。
本文档介绍如何为 SignalR 服务器和客户端启用和配置跟踪。 跟踪使你能够查看有关 SignalR 应用程序中事件的诊断信息。
本主题最初由帕特里克·弗莱彻撰写。
本教程中使用的软件版本
- Visual Studio 2013
- .NET Framework 4.5
- SignalR 版本 2
问题和评论
请留下反馈,说明你对本教程的喜爱程度,以及我们可以在页面底部的评论中改进的内容。 如果你有与本教程不直接相关的问题,可以将其发布到 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>
事件记录在应用程序日志中,并通过事件查看器提供,如下所示:
注意
使用事件日志时,将 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
时,传入当前 SynchronizationContext 和 StackPanel ,它将在其中创建用于跟踪输出的 TextBlock :
Connection = new HubConnection(ServerURI);
var writer = new TextBlockWriter(SynchronizationContext.Current, StackPanelConsole);
Connection.TraceWriter = writer;
Connection.TraceLevel = TraceLevels.All;
然后,跟踪输出将写入传入的 StackPanel 中创建的新 TextBlock:
将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 客户端。 它在浏览器控制台中显示连接和中心调用事件: