2016-11-16 6 views
1

私は時折シグナルハブに接続してメッセージをブロードキャストするいくつかのwebジョブを持っています。以下は単なる例です。この例では、TimerTrigger属性を持つ開発用の単純なWebジョブで、20秒ごとに連続して実行するように設定されています。以下のコードに示すように。AzureのWebジョブとSignalRメモリリーク

public static void Main() 
    { 

     JobHostConfiguration config = new JobHostConfiguration(); 
     config.Tracing.ConsoleLevel = TraceLevel.Verbose; 
     config.UseTimers(); 
     if (config.IsDevelopment) 
     { 
      config.UseDevelopmentSettings(); 
     } 
     var host = new JobHost(config); 
     host.RunAndBlock(); 
    } 

    public static void ProcessPush([TimerTrigger("00:00:20", RunOnStartup = true)] TimerInfo timerInfo, TextWriter log) 
    { 
     // Send a signalr message to the Hub 
     try 
     {    
      SendMessageToHub(log); 
     } 
     catch (Exception e) 
     { 
      log.WriteLine($"WebJob Push Exception: {e.Message}"); 
     } 
    } 

    private static async Task SendMessageToHub(TextWriter log) 
    { 
      var hub = new HubConnection(CloudConfigurationManager.GetSetting("MyWebSite")); 
      var proxy = _hub.CreateHubProxy("MyHub"); 

      log.WriteLine("WebJob Push: Sending message to SignalR Hub."); 
      if (_hub.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Disconnected) 
      { 
       await _hub.Start(); 
      } 
      await _proxy.Invoke("BroadcastMessage"); 
      log.WriteLine("WebJob Push: Sent message to SignalR Hub."); 
    } 

ウェブサイトやsignalrハブをホストするサーバ上のメモリの増加は常にあります。 WebサイトのIISログを調査すると、長いポーリングを使用してPOSTメッセージのサージ/バッチが同じ秒でWebサイトに送信されるようです。しばらく待ってから別のバッチのメッセージで攻撃を受けます。ところで、これはIISサーバー上のCPUも狂ってしまいます。この記事の一番下には、IISログエントリの例があります。

私は、Webジョブからシグナルメッセージを定期的なパルスメッセージで一貫して送信できるようにしたいと考えています(Webジョブを拡張したいと考えています。 )。

2016年11月15日23時10: -

敬具、

ステファン

例IISログエントリは、彼らがすべて離れて20秒の代わりに、同じ秒以内に来て気づきます:35 POST/signalr /ポーリングclientProtocol = 1.4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHubの%22%7D] & connectionToken = TBbNVDpndk0riu8UvVzbGJrWjYIo7eMLcP4lk7ABV74OBMbZRTJrCRL1bzsPxpd1Tyle2rS3tV2JJrigninhu880ml51Xers76PPDX0Hf97dTBYR4k%2BVc2V9KAmiGt0p & messageId = d-80E0087-B%2C7D%7CEz%2C0%7CE0%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 5343

2016年11月15日午後11時10分35秒POST/signalr /ポーリングclientProtocol = 1.4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHubの%22%7D] & connectionToken = KYwQXpNrPIU21NXMa0So5u42EwXTcMlGyLqL3tetx4WfOtTunHLclG%2BhPd% 2BcPeZPmfe6KKvQL13XIU1W5fApuTv0XN5XFPoNUmyBjhhISoqodwcZeu3QKmkbaXcpHMtE &イベントID = D-80E0087-B%2C7D%7Cav%2C0%7Caw%2C2 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 +(マイクロソフトのWindows + + NT + 6.2.9200.0) - 200 0 10641

2016-11-15 23:10:35 POST/signalr/po LL clientProtocol = 1.4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHub%で22%の7D] & connectionTokenは= NO%2BPZ8M5JJOpiobpJUV5%2FZvQyEKYjp%2FOuqQ%2F0Bkq05TKRJZfeI%2FD%2BxRyPC7EsAAjXVqJr05PksorlMWrXocGkskfVsLU2Qvtx%2Fi1O8hU5lNz4KcoSc%2Bkv%2BlDpr2AZBLv &のmessageId = 80 -0000-B%2C7D%7CFB%2C0%7CFC%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 18282

2016年11月15日23時十分35秒POST/signalr /ポーリングclientProtocol = 1.4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHubの%22%7D] & connectionToken = wiGSRiNHdd7crhkcAMd%2FWy%2F3qGRZ5WdBm% 2BdbR3b7aTbtpB8aaBGDil%2FqAWha6Si5eEohsUmCxAU4Pkefy%2BNoxoG9fgYC4R66 ErXIShyBUcsNLWo1AyH5zGDk7bFvme3E & messageId = d-80E0087-B%2C7D%7CE9%2C0%7CE_%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 11360

2016-11-15 23:10:35 POST/signalr/poll clientProtocol = 1。4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHubの%22%7D] & connectionToken = hEJ1b0%2Bz2eeyC8IvYmOV3ffZ%2FAFQiQpEnJLUmCZTEVDLwcgOqhyQbQnu0R29sazp6BxcK4WsDhSbEdg2Sh4wMBSZjQtKMzASr2Fa2eY2HGgoVJcfDOMixQX2FCqfa%2BmP &イベントID = D-80E0087-B%2C7D%7CFD%2C0%7CFE% 2 0 0 15798

2016-11-15 23:10:35 POST/signalr/2C0 443 - ポーリングclientProtocol = 1.4 &輸送= longPolling & connectionDataは= [%7B%22Nameの%22:%22MyHubの%22%7D] & connectionToken = 2UsU63IHgaNO%2BBYmoamsKxFq7Vv3uaGigvR1NrGnntVnAbTg2C0%2BVXZnA9aT8siqpkBv%2Fo8avvvNTSBfQD77IspaO6jOnSU8rXMXDU2Vr6ojkWr%2Fwt1LFsdNy3%2BHpDGC & messageId = d-80E0087-B%2C7D%7CEv%2C0%7CEw%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 11844

など、など

UPDATE - 明示的にハブの接続を停止するには、(同じウェブ・ジョブ・クライアントまたは余分クライアント)孤児クライアントを扱っているようです。特に、_hub.Stop()を追加する。プロキシを呼び出した後

+0

ポーリング要求は、それぞれ異なるクライアント(それぞれが異なるconnectionTokenを持つ)からのものです。これは、サーバーが既存のポーリング要求でクライアントにメッセージを送信し、クライアントが新しいメッセージを取得するために新しいポーリングを再確立する必要があることを意味します。これらの要求を避けたい場合は、より効率的な輸送、理想的にはウェブソケットを使用してください。 (クライアントが実際に長いポーリングを実行しているのは興味深いことですが、デフォルトでは無効になっているためWebSocketを使用していないと思われますが、有効にするのを忘れていたかもしれませんが、serverSentEventsを使用していない理由はわかりません) – Pawel

+0

あなたのトリガされた関数を非同期にし、SendMessageToHubメソッドのシグネチャで 'async void'を' async Task'に変更してみてください。 – Thomas

+0

こんにちはトーマス、申し訳ありませんが、ここでコード例を編集しました。それは実際には:プライベート静的非同期タスクSendMessageToHub(TextWriterログ) –

答えて

2

これは、メッセージが送信された後でハブ接続を確実に停止するためのものです。以下はコメントに囲まれた行のコードです。

ブラウザクライアントとは異なり、クライアントがしばらくしばらくしてから切断されるように見えます。 webjobクライアントは、ウェブサイトをポーリングし続けます。したがって、Webjobが(タイマーを介して、または空白のキューまたはトピックからメッセージを読むことによって)トリガされるたびに、新しいクライアントを生成し続け、その接続を保持します。

Webjobでは、接続を明示的に停止する必要があります。そうしないと、メモリとCPUが徐々にナイトバッグになります。

private static async Task SendMessageToHub(TextWriter log) 
{ 
     var hub = new HubConnection(CloudConfigurationManager.GetSetting("MyWebSite")); 
     var proxy = _hub.CreateHubProxy("MyHub"); 

     log.WriteLine("WebJob Push: Sending message to SignalR Hub."); 
     if (_hub.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Disconnected) 
     { 
      await _hub.Start(); 
     } 
     await _proxy.Invoke("BroadcastMessage"); 
     ///////////////////////////////////////////////////////////// 
     // Stopping the hub connection is necesssary in a web job // 
     _hub.Stop(); 
     ///////////////////////////////////////////////////////////// 
     log.WriteLine("WebJob Push: Sent message to SignalR Hub."); 
} 
+0

接続を停止した後にハブメソッドを呼び出すのはおそらく間違いです – Pawel

+0

Thanks Pawel、ここでは間違った場所に行を置いていますが、stackoverflowのポストを編集しています(コードは正しい)。 –

関連する問題