2016-11-02 3 views
6

Я прочитал много статей о том, что клиент должен закрыть соединение с client.Close(), поэтому предел по умолчанию для WCF не будет превышен. Есть, у меня есть работа WCF WebGet, которая в основном просто возвращает изображение.Wcf внезапно зависает (работа в сети)

[ServiceContract(SessionMode = SessionMode.NotAllowed)] 
[ValidationBehavior] 
public interface IImagesService 
{ 
    [OperationContract(Name = "ImagesGet4")] 
    [WebGet(UriTemplate = "/Image/{partner}/{id}/{image}_{width}_{height}.jpg")] 
    Stream ImagesGet2(string partner, string id, string image, string width, string height); 
    } 

В этой ситуации клиент является браузером, и все, что я делаю с конфигурацией wcf, не помогает. maxConnections,maxReceivedMessageSize,maxBytesPerRead и множество других параметров увеличено и до сих пор не повезло.

РЕДАКТИРОВАТЬ: Это дополнительный код: ImageGet метод, который называется службой:

 public Stream ImagesGet(string partner, string id, string image, string  width = null, string height = null) 
     { 
      WSData.EventLogs.MinimalEventSource.Log.ClientIp(""); 
      WSData.EventLogs.MinimalEventSource.Log.ServicePath(""); 
      WSData.EventLogs.MinimalEventSource.Log.Message(DateTime.Now + " | " + partner); 


     bool cache; 
     var images = new Images(); 
     var stream = images.ImagesGetStream(out cache, partner, id, image, width, height); 

     if (cache) 
     { 
      WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control", "public, max-age=604800"); 
      WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.Today; 
      WebOperationContext.Current.OutgoingResponse.SetETag(id); 
     } 

     WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; 

     OperationContext clientContext = OperationContext.Current; 
     clientContext.OperationCompleted += new EventHandler(delegate (object sender, EventArgs args) 
     { 
      if (stream != null) 
       stream.Dispose(); 
     }); 


     return stream; 
    } 

ImagesGetStream метод, который называется описанным выше способом является:

public Stream ImagesGetStream(out bool cache, string partner, string id, string image, string width = null, string height = null, string background = null) 
    { 

     string PARTNER = partner; 
     cache = true; 

     try 
     { 
      EventLogs.MinimalEventSource.Log.Load(10, "DatabaseCall"); 
      var img = ImagesDL.GetImage(PARTNER, new PrimaryKey(id)); 
      EventLogs.MinimalEventSource.Log.Unload(13); 

      EventLogs.MinimalEventSource.Log.Load(14, "GettingImageDir"); 
      var imagesRoot = Path.Combine(BaseConfiguration.GetDocumentsSharedDirectory(PARTNER), img.Url); 


      var isWatermarked = img.Group.Contains("WEBES") == false && (partner.ToUpper() == "ZG-ADRIAGATE1" || partner.ToUpper() == "LENIO-ADRIAGATE2" || partner.ToUpper() == "LENIO"); 

      EventLogs.MinimalEventSource.Log.Unload(15); 

      EventLogs.MinimalEventSource.Log.Load(16, "ImageToStream"); 
      var stream = new FileStream(imagesRoot, FileMode.Open, FileAccess.Read, FileShare.Read); 
      EventLogs.MinimalEventSource.Log.Unload(17); 


      if (!string.IsNullOrEmpty(width)) 
      { 
       var isBackground = !string.IsNullOrEmpty(background); 

       int widthp = 0; 
       int heightp = 0; 

       int.TryParse(width, out widthp); 
       int.TryParse(height, out heightp); 

       return ResizeImage(partner, stream, new Size(widthp, heightp), isBackground, img.Guest, isWatermarked, background); 
      } 
      else if(img.Group.Contains("WEBES") == false) { 

       Image imgToResize = Image.FromStream(stream); 

       if(imgToResize.Width > imgToResize.Height && imgToResize.Width > 2048) 
        return ResizeImage(partner, stream, new Size(2048, 1536), false, img.Guest, isWatermarked, background); 

       else if (imgToResize.Width < imgToResize.Height && imgToResize.Height > 2048) 
        return ResizeImage(partner, stream, new Size(1536, 2048), false, img.Guest, isWatermarked, background); 

       else if (imgToResize.Width == imgToResize.Height && imgToResize.Height > 2048) 
        return ResizeImage(partner, stream, new Size(2048, 2048), false, img.Guest, isWatermarked, background); 
      } 

      return isWatermarked ? WatermarkingImage(partner, stream, img.Guest, isWatermarked) : stream; 



     } 
     catch (Exception) 
     { 
      cache = false; 
      return new FileStream(AppPath + @"\App_Resorces\NoImage.jpg", FileMode.Open, FileAccess.Read, FileShare.Read); 
     } 
    } 

Это является важной частью конфигурации:

<service name="WSTraveller.ImagesService" behaviorConfiguration="ServiceBehavior"> 
    <endpoint address="soap" binding="basicHttpBinding" behaviorConfiguration="soapBehavior" contract="WSTraveller.IImagesService" bindingConfiguration="soapBinding" bindingName="soapBinding" bindingNamespace="http://ws.adriagate.com/TRWS/ImagesService.svc/soap"/> 
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="WSTraveller.IImagesService" bindingConfiguration="webBinding" bindingName="webBinding" bindingNamespace="http://ws.adriagate.com/TRWS/ImagesService.svc/pox"/> 
    </service> 

...

 <basicHttpBinding> 
    <binding name="soapBinding" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" messageEncoding="Text"> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/> 
     <security mode="None"/> 
    </binding> 
    </basicHttpBinding> 
+0

Вы когда-нибудь прослеживали код сервера и пытались реплицировать свою проблему во время отладки? –

+0

Да, однажды перестали работать после вызова базы данных, но для меня кажется маловероятным, что это проблема, потому что это очень простой запрос.Выберите один элемент из таблицы «Изображения». У меня больше нет подробностей сейчас до понедельника, потому что мой колледж работает над решением этой проблемы. –

+0

На этот вопрос нельзя ответить даже с бесконечной щедростью без кода. Кажется, что вы смогли воспроизвести проблему (?). Поместите стек вызовов висячего потока, включая внешний код. – usr

ответ

1

Мои два cents..check, если это поможет вам:

1) сожмите изображение с помощью потока GZIP или так, в нашем проекте мы должны были отправить огромные массивы данных через провод, используя wcf, чтобы мы сжимали, а затем отправляли его.

2) если база данных является узким местом, вы можете сделать асинхронный вызов db и использовать механизм очереди для хранения результатов, а запрос клиента wcf будет пытаться и вывести результат из очереди через регулярный интервал.

1

Перед повторным использованием пула приложений возьмите свалку памяти. Если у вас есть Visual Studio Enterprise, вы можете открыть дамп в приятном gui и увидеть трассировку стека всех потоков .NET в этом процессе. Поскольку приложение больше не отвечает на запросы, существует очень хороший шанс, что большинство трассировок стека будут находиться в одном месте, что скажет вам, где в коде проблема. Тогда вы знаете, где сосредоточить свои усилия.

1

От MSDN:

По умолчанию, HTTP, TCP/IP и именованный канал транспортирует использование буферной передачи сообщений.

Буферизованные передачи сохраняют все сообщение в буфере памяти до завершения передачи.

Поскольку вы не указали, в конфигурации, чтобы использовать Поточный, он использует Буферизированный в режиме передачи. Поэтому возможно, что ваш процесс работает на низкой памяти из-за большого количества (в зависимости от количества или запросов) огромных файлов, хранящихся в памяти.

Внесите необходимые изменения и повторите попытку. Я думаю, это решит проблему.

+0

Привет, мой коллега работает над этой проблемой, и я уже предложил ему это решение. –