我有一个奇怪的问题。我的.NET DataController向Java服务器(REST)发送响应。一切正常,但是当我经常发送响应时,突然GetResponse方法不会回来就会挂起。 我不知道问题是什么。
这是我的代码
ServicePointManager.DefaultConnectionLimit = 20;
public string HttpGet(string url, string requestAccept)
{
if(string.IsNullOrEmpty(url))
throw new Exception("HttpGet: no REST service URL provided");
if(string.IsNullOrEmpty(requestAccept))
requestAccept = defaultRequestAccept;
if(!url.Equals("pc/alive"))
{
if(string.IsNullOrEmpty(SessionId))
{
if(string.IsNullOrEmpty(Authorization()))
throw new WebException("HttpGet: no login");
}
}
int tries = RestAccessData.MaxReconnect;
string result = string.Empty;
do
{
try
{
var request = NewWebRequest(url, "GET", false, true, requestAccept);
using(var response = request.GetResponse() as HttpWebResponse)
{
UpdateSessionId(response);
HttpStatusCode statusCode = response.StatusCode;
LOG.Debug("...StatusCode: {0} ({1})", (int) response.StatusCode, response.StatusDescription);
if((int) response.StatusCode < 500)
lastContactWithServer = DateTime.Now.Ticks;
switch(statusCode)
{
// Informational 1xx
case HttpStatusCode.Continue: // 100
case HttpStatusCode.SwitchingProtocols: // 101
throw new HttpResponseException(response);
// Successful 2xx
case HttpStatusCode.OK: // 200
result = ReadContent(response);
response.Close();
return (result);
case HttpStatusCode.NoContent: // 204 The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation.
response.Close();
return (string.Empty);
case HttpStatusCode.Created: // 201
case HttpStatusCode.NonAuthoritativeInformation: // 203
result = ReadContent(response);
throw new HttpResponseException(response, result);
case HttpStatusCode.Accepted: // 202 The request has been accepted for processing, but the processing has not been completed.
case HttpStatusCode.ResetContent: // 205 The server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent.
case HttpStatusCode.PartialContent: // 206 The server has fulfilled the partial GET request for the resource.
throw new HttpResponseException(response);
case HttpStatusCode.Unauthorized:
throw new HttpResponseException(response);
default:
throw new HttpResponseException(response);
}
}
}
catch(WebException ex)
{
HandleWebException(ex);
}
catch(HttpResponseException ex)
{
throw ex;
}
catch(SystemException ex)
{
LOG.Error(ex, "caused a(n) {0}", ex.GetType().Name);
}
catch(Exception ex)
{
LOG.Warn(ex, "HttpGet: An error occured while trying to contact the server. Reason: {0}", ex.Message);
throw new UserException("An error occured while trying to contact the server.", ex);
}
}
while(0 < tries--);
return (string.Empty);
}
private HttpWebRequest NewWebRequest(string urlAsString, string requestType, bool withContentType, bool applicationJson, string requestAccept)
{
urlAsString = string.Format("{0}{1}", RestAccessData.GetUrl(), EncodeUrl(urlAsString));
Uri url;
if(!Uri.TryCreate(urlAsString, UriKind.Absolute, out url))
throw new NotSupportedException("url is not compatible");
LOG.Info("RESTUrl {0}", urlAsString);
try
{
var request = HttpWebRequest.Create(url) as HttpWebRequest;
if(!string.IsNullOrEmpty(SessionId))
{
CookieContainer cookies = new CookieContainer();
Cookie cookie = new Cookie
{
Name = "JSESSIONID",
Value = SessionId,
Domain = url.Host
};
cookies.Add(cookie);
request.CookieContainer = cookies;
}
request.Timeout = RestAccessData.Timeout;
request.Method = requestType;
request.AllowAutoRedirect = true;
request.AllowWriteStreamBuffering = true;
request.KeepAlive = false;
request.ContentLength = 0;
request.Headers["Accept-Charset"] = "utf-8";
request.Accept = requestAccept;
request.UserAgent = LvsClient;
if(withContentType)
request.ContentType = applicationJson ? defaultApplicationJson : defaultApplicationWwwForm;
if(!string.IsNullOrEmpty(credential.UserName) && !string.IsNullOrEmpty(credential.Password))
request.Headers["Authorization"] = string.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credential.UserName, credential.Password))));
return (request);
}
catch(Exception ex)
{
throw new UserException(TH.Translate("NewWebRequest caused an error"), ex);
}
}
问题出在哪里?
答案 0 :(得分:0)
这条线让我感到不舒服:
using(var response = request.GetResponse() as HttpWebResponse)
如果响应不是HttpWebResponse
,那么它永远不会被处理 - as
运算符会给你'null。
答案 1 :(得分:0)
我找到了解决方案。这篇关于Understanding MaxServicePointIdleTime and DefaultConnectionLimit的MSDN文章非常有用。使用 MaxServicePointIdleTime 属性后,阅读此评论
我在连接活动和连接关闭之间找到了一个很好的平衡点。使用MaxServicePointIdleTime和DefaultConnectionLimit后,我的客户端工作正常。