SignalR トレースを有効にする

作成者: Tom FitzMacken

警告

このドキュメントは、最新版の SignalR を対象としていません。 ASP.NET Core SignalR に関する記事を参照してください。

このドキュメントでは、SignalR サーバーとクライアントのトレースを有効にして構成する方法について説明します。 トレースを使うと、SignalR アプリケーションのイベントに関する診断情報を表示できます。

このトピックは、もともと Patrick Fletcher によって書かれました。

チュートリアルで使用するソフトウェアのバージョン

質問とコメント

このチュートリアルの感想、改善に関するフィードバックをページの下部にあるコメント欄にお寄せください。 チュートリアルに直接関連しない質問がある場合は、ASP.NET SignalR フォーラムまたは StackOverflow.com に投稿できます。

トレースが有効な場合、SignalR アプリケーションはイベントのログ エントリを作成します。 クライアントとサーバーの両方からイベントをログできます。 サーバーでのトレースでは、接続、スケールアウト プロバイダー、メッセージ バスのイベントがログされます。 クライアントでのトレースでは、接続のイベントがログされます。 SignalR 2.1 以降では、クライアントでのトレースにより、ハブ呼び出しメッセージの完全な内容がログされます。

内容

サーバーでのトレースの有効化

アプリケーションの構成ファイル (プロジェクトの種類に応じて App.config か Web.config のいずれか) 内でサーバーでのトレースを有効にします。ログするイベントのカテゴリを指定します。 構成ファイルでは、イベントをテキスト ファイル、Windows イベント ログ、または TraceListener の実装を使ったカスタム ログのいずれにログするかについても指定します。

サーバー イベントのカテゴリには次の種類のメッセージが含まれます。

ソース [メッセージ]
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 トランスポートの接続、切断、キープアライブ イベント
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>

イベントはアプリケーション ログにログされ、以下に示すようにイベント ビューアーを介して使用できます。

Event Viewer showing SignalR logs

Note

イベント ログを使う場合は、メッセージ数を管理しやすい状態に保つために、TraceLevelError に設定します。

.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.OutStreamWriter を使ったファイルへの書き込みは使用できません。 代わりに、トレース用の TextWriter のカスタム実装を作成する必要があります。

Windows Phone クライアントのイベントを UI にログする

SignalR コードベースには、TextBlockWriter というカスタムの TextWriter 実装を使ってトレース出力を TextBlock に書き込む Windows Phone サンプルが含まれています。 このクラスは、samples/Microsoft.AspNet.SignalR.Client.WP8.Samples プロジェクトにあります。 TextBlockWriter のインスタンスを作成するときは、現在の SynchronizationContext と、トレース出力に使う TextBlock を作成する StackPanel を渡します。

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

トレース出力は、渡した StackPanel 内に作成された新しい TextBlock に書き込まれます。

Screenshot that shows a Windows Phone sample with output in the display.

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 のデバッグ ウィンドウに書き込まれます。

Screenshot that shows the Output dialog box. Debug is in the Show output from field.

JavaScript クライアントでのトレースの有効化

接続でクライアント側のログを有効にするには、start メソッドを呼び出して接続を確立する前に、接続オブジェクトで logging プロパティを設定します。

ブラウザー コンソールへのトレースを有効にするためのクライアント JavaScript コード (生成されたプロキシを使用)

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

ブラウザー コンソールへのトレースを有効にするためのクライアント JavaScript コード (生成されたプロキシを使用しない)

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

トレースが有効になっている場合、JavaScript クライアントはブラウザー コンソールにイベントをログします。 ブラウザー コンソールにアクセスするには、「トランスポートの監視」を参照してください。

次のスクリーンショットは、トレースが有効になっている SignalR JavaScript クライアントを示しています。 ブラウザー コンソールに接続とハブ呼び出しのイベントが表示されます。

SignalR tracing events in the browser console