2017-03-09 3 views
0

클라이언트 데스크톱 응용 프로그램과 웹 서비스가 외부 서버 (IIS)에 배포되었습니다. 이들 사이의 통신은 HttpWebRequest 및 HttpWebResponse를 기반으로합니다. 이 코드는 IIS 8.0에서 제대로 작동했으며 IIS 8.5로 업그레이드 한 후 응답을 클라이언트에 보내면 작동이 중지되었습니다. 원격 호스트에 의해
기존 연결 강제 폐쇄 하였다IIS 웹 응답 연결 강제 종료 문제

System.IO.IOException : 반송 접속으로부터 데이터를 판독 할 수 없음을 다음과 같은 예외가 클라이언트 측에서 발생한다. --->
System.Net.Sockets.SocketException :
기존 연결이 원격 호스트에 의해 강제로 닫혔습니다
System.Net.Sockets.Socket.Receive (Byte [] 버퍼, Int32 오프셋, Int32 크기, System.Net.ConnectStream에서 System.Net.Sockets.NetworkStream.Read에서 socketFlags socketFlags)
(바이트 [] 버퍼 INT32 오프셋, INT32 사이즈)
--- 내부 예외 스택 추적 --- 끝

.Read (Byte [] 버퍼, Int32 오프셋, Int32 크기)
at System.IO.Stream.InternalCopyTo (스트림 대상, Int32 버퍼 크기)
Test.TestH ttpService.GetResponseString (HttpWebResponse 응답)

서버 쪽에서 예외가 발생하지 않습니다. 서버상의 Wireshark와 클라이언트 컴퓨터의 Fiddler 역시 단서를 제공하지 않습니다.

public static string GetResponse(string serviceUrl, string resourceUrl, string method, string xmlRequestBody, string authorization, string connectionName) 
    { 
     string responseMessage = null; 
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 
     var request = HttpWebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest; 
     if (request != null) 
     { 
      request.ContentType = "application/xml"; 
      request.Method = method; 
      request.KeepAlive = false; 
      request.ProtocolVersion = HttpVersion.Version10; 
      request.Timeout = int.MaxValue; 
      //request.ServicePoint.ConnectionLimit = 1; 
      request.Headers.Add("Authorization", authorization); 
      request.Headers.Add("ConnectionName", connectionName); 
     } 

     if (xmlRequestBody != null) 
     { 
      byte[] requestBodyBytes = TBCCompressionService.Zip(xmlRequestBody.ToString()); 
      request.ContentLength = requestBodyBytes.Length; 
      if (request.ContentLength > 0) 
      { 
       using (Stream postStream = request.GetRequestStream()) 
       { 
        postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length); 
       } 
      } 
     } 

     if (request != null) 
     { 
      System.Net.ServicePointManager.Expect100Continue = false; 
      try 
      { 
       var response = request.GetResponse() as HttpWebResponse; 
       if (response.StatusCode == HttpStatusCode.OK) 
       { 
        responseMessage = GetResponseString(response); 
       } 
       else 
       { 
        responseMessage = response.StatusDescription; 
       } 
      } 
      catch(WebException ex) 
      { 
       var httpResponse = ex.Response as HttpWebResponse; 
       if (httpResponse != null 
        && httpResponse.StatusCode == HttpStatusCode.BadRequest) 
       { 
        responseMessage = GetResponseString(ex.Response as HttpWebResponse); 
       } 
       else 
       { 
        throw ex; 
       } 
      } 
     } 
     return responseMessage; 
    } 
private static string GetResponseString(HttpWebResponse response) 
    { 
     string result = string.Empty; 

     if(response != null) 
     { 
      using (Stream responseStream = response.GetResponseStream()) 
      { 
       if (responseStream != null) 
       { 
        using (MemoryStream memoryStream = new MemoryStream()) 
        { 
         //this is the line when above exception is thrown. 
         responseStream.CopyTo(memoryStream); 
         result = TBCCompressionService.UnZip(memoryStream.ToArray()); 
        } 
       } 
      } 
     } 
     return result; 
    } 

서버 측 코드 :

public static void Send(string responseContent, HttpStatusCode? httpStatus) 
{ 
    HttpResponse response = HttpContext.Current.Response; 
    int waitCounter = 1000; 
    if (response.IsClientConnected) 
    { 
     response.Clear(); 
     response.BufferOutput = true; 
     response.Buffer = true; 

     if (httpStatus != null) 
     { 
      response.StatusCode = (int)httpStatus.Value; 
     } 

     if (responseContent == null 
      || string.IsNullOrWhiteSpace(responseContent)) 
     { 
      response.StatusCode = (int)HttpStatusCode.NoContent; 
     } 
     else 
     { 
      byte[] responseContentZip = Zip(responseContent); 
      int responseContentLength = responseContentZip.Length; 
      response.ContentType = "text/xml"; 
      response.AppendHeader("Content-Length", responseContentLength.ToString()); 
      response.BinaryWrite(responseContentZip); 
     } 
      response.Flush(); 
      //If this sleep is not present exception is thrown on the client side 
      //Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host. 
      System.Threading.Thread.Sleep(waitCounter); 
      response.Close(); 
      response.End(); 
    } 
    else 
    { 
     logger.Error("Client was no longer connected to remote server. Response wasn't sent."); 
    } 
} 

아주 이상한 일이 있다는 것입니다 IIS 추적 로그는

enter image description here

클라이언트 측 코드는 모든 데이터가 성공적으로 클라이언트에 전송 된 것을 보여줍니다 잠자는 AppPool 스레드는 응답을 클라이언트에 성공적으로 전달하도록 도와줍니다. 플러시 작업이 연결이 닫히기 전에 끝나지 않는 것처럼 보입니다. System.Web.dll 코드에서 몇 가지 실마리를 찾았지만이 경우 플러시가 비동기 적으로 실행되거나 실행 중 끊어지는 연결을 가리키는 것이 아닙니다.

+0

당신은 이벤트 로그를 보면나요 **? –

+0

예. 내가 했었고이 연결로 어떤 일이 일어나는지 전혀 알지 못합니다. – RadMi

답변

0

U는 서비스 포인트의 수를 제한하는 목적에 사용

** webRequest.ServicePoint.ConnectionLimit = 1;

+0

나는 이미 이것을 시도했다 - 아무 결과도. – RadMi