2016-11-16 4 views
1

그래서 나는 때때로 시그널 허브에 연결하여 메시지를 브로드 캐스트하는 일부 웹 작업을 가지고 있습니다. 아래는 단지 하나의 예입니다.이 경우 TimerTrigger 속성을 사용하여 개발을위한 간단한 웹 작업이 매 20 초마다 계속 실행되도록 설정되어 있습니다. 아래 코드에 표시된 것과 같습니다.Azure 웹 작업 및 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."); 
    } 

웹 사이트 및 신호기 허브를 호스팅하는 서버의 메모리가 항상 증가합니다. 웹 사이트의 IIS 로그를 조사 할 때 긴 폴링을 사용하여 같은 초에 POST 메시지의 서지/배치를 웹 사이트에 올리는 것으로 보입니다. 그런 다음 잠시 기다린 다음 다른 메시지 묶음으로 포격을받습니다. 그건 그렇고, 이것은 IIS 서버의 CPU를 미친 듯이 구동시킵니다. 이 게시물의 맨 아래에 IIS 로그 항목의 예가 나와 있습니다.

저는 정기적 인 펄스 메시지와 함께 웹 작업에서 신호 메시지를 보낼 수 있기를 원합니다. (우리는 웹 작업을 확장하고 싶습니다. 지금은 타이머로 실행된다는 사실을 변명하십시오.).

2016년 11월 15일 23시 10분 : -

종류와 관련,

스테판

예 IIS 로그 항목은 모두 떨어져 20 초 대신, 같은 초 이내에서 온 통지 35 POST/signalr/폴 때 clientProtocol = 1.4 & & 트랜스 = longPolling connectionData = [% 7B 22Name %의 % 22 % 22 %의 22MyHub % 7D] = & connectionToken TBbNVDpndk0riu8UvVzbGJrWjYIo7eMLcP4lk7ABV74OBMbZRTJrCRL1bzsPxpd1Tyle2rS3tV2JJrigninhu880ml51Xers76PPDX0Hf97dTBYR4k % 2BVc2V9KAmiGt0pmessageId = 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일 23시 10분 35초 POST/signalr/폴 때 clientProtocol = 1.4 & & 트랜스 = longPolling connectionData = [% 7B 22Name %의 % 22 % 22 %의 22MyHub % 7D] = & connectionToken KYwQXpNrPIU21NXMa0So5u42EwXTcMlGyLqL3tetx4WfOtTunHLclG % 2BhPd % 2BcPeZPmfe6KKvQL13XIU1W5fApuTv0XN5XFPoNUmyBjhhISoqodwcZeu3QKmkbaXcpHMtE & messageId가 = D-B-80E0087 % 2C7D % 7Cav % 2C0 % 7Caw % 2C2 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 + (+ 마이크로 소프트 윈도우 NT + + 6.2.9200.0) - 200 0 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시 10분 35초 POST/signalr/폴 때 clientProtocol = 1.4 & & 트랜스 = longPolling connectionData = [% 7B 22Name %의 % 22 % 22 %의 22MyHub % 7D] = & connectionToken wiGSRiNHdd7crhkcAMd 2FWy % % % 2F3qGRZ5WdBm 2BdbR3b7aTbtpB8aaBGDil % 2FqAWha6Si5eEohsUmCxAU4Pkefy % 2BNoxoG9fgYC4R66 (Windows + NT + 6.2.9200.0) - 200 0 0 11360 SignalR.Client.NET45/2.2.1.0 + (Microsoft + Windows + NT + 6.2.9200.0) - 오류 코드 : 0x00000000 메시지 번호 : d-80E0087-B % 2C7D % 7CE9 % 2C0 % 7CE_ % 2C0 443 - 104.210.116.149

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 & messageId가 = D-80E0087-B % 2C7D % 7CFD % 2C0 % 7CFE % 2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0 + (Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 15798

2016-11-15 23:10:35 POST/signalr/폴링 때 clientProtocol = 1.4 & & 트랜스 = longPolling connectionData = [% 7B 22Name %의 % 22 % 22 %의 22MyHub % 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을 가짐)로부터 온 것입니다. 서버가 기존 폴링 요청에서 클라이언트에 메시지를 보낸 경우에만 클라이언트는 새로운 폴링을 다시 설정하여 새 메시지를 가져와야합니다. 이러한 요청을 피하려면보다 효율적인 전송을 사용하십시오. 이상적으로는 웹 소켓입니다. (클라이언트가 실제로 긴 폴링을 실행하는 것은 흥미 롭습니다. 웹 소켓을 사용하지 않는 것은 기본적으로 사용되지 않기 때문에 사용할 수는 없지만 serverSentEvents를 사용하지 않는 이유는 모르겠습니다) – Pawel

+0

당신의 트리거 함수를 비동기로 만들고'async void'를 SendMessageToHub 메소드 서명에서'async Task'로 변경하십시오. – Thomas

+0

안녕하세요, Thomas, 죄송합니다. 여기서 코드 예제를 편집했습니다. 그것은 실제로 : 개인 정적 비동기 작업 SendMessageToHub (TextWriter 로그) –

답변

2

분명히 들릴지도 모르겠지만 메시지에 메시지를 보낸 후 허브 연결을 중단해야합니다. 다음은 주석으로 둘러싸인 추가 라인이있는 코드입니다.

브라우저 클라이언트와 달리 잠시 후 클라이언트가 연결 해제되는 것처럼 보일 수 있습니다. Webjob 클라이언트는 계속해서 웹 사이트를 폴링합니다. 그래서 WebJob이 트리거 될 때마다 (타이머를 통해 또는 푸른 대기열이나 주제에서 메시지를 읽음으로써) 새로운 클라이언트를 생성하고 그 연결을 유지합니다.

Webjob에서 명시 적으로 연결을 중지해야합니다. 그렇지 않으면 메모리와 CPU가 점차적으로 nutbags가됩니다.

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 (코드에서 맞음)에서 게시물을 편집하는 동안 여기에 잘못된 지점에 줄을 넣었습니다. 대답에서 해결했습니다. –