Я пишу приложение, которое проксирует некоторые HTTP-запросы, используя веб-API ASP.NET, и я изо всех сил пытаюсь определить источник прерывистой ошибки. Это похоже на состояние гонки... но я не совсем уверен.
Прежде чем я расскажу подробнее, это общий коммуникационный поток приложения:
- Клиент делает HTTP-запрос прокси 1.
- Прокси 1 перенаправляет содержимое HTTP-запроса на Proxy 2
- Прокси 2 передает содержимое HTTP-запроса в целевое веб-приложение
- Целевое веб-приложение отвечает на HTTP-запрос, и ответ передается (передача по каналам) в Proxy 2
- Прокси 2 возвращает ответ Прокси 1, который в свою очередь отвечает на исходный вызов Клиент.
Приложения Proxy записываются в RTM веб-API ASP.NET с использованием .NET 4.5. Код для выполнения реле выглядит так:
//Controller entry point.
public HttpResponseMessage Post()
{
using (var client = new HttpClient())
{
var request = BuildRelayHttpRequest(this.Request);
//HttpCompletionOption.ResponseHeadersRead - so that I can start streaming the response as soon
//As it begins to filter in.
var relayResult = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
var returnMessage = BuildResponse(relayResult);
return returnMessage;
}
}
private static HttpRequestMessage BuildRelayHttpRequest(HttpRequestMessage incomingRequest)
{
var requestUri = BuildRequestUri();
var relayRequest = new HttpRequestMessage(incomingRequest.Method, requestUri);
if (incomingRequest.Method != HttpMethod.Get && incomingRequest.Content != null)
{
relayRequest.Content = incomingRequest.Content;
}
//Copies all safe HTTP headers (mainly content) to the relay request
CopyHeaders(relayRequest, incomingRequest);
return relayRequest;
}
private static HttpRequestMessage BuildResponse(HttpResponseMessage responseMessage)
{
var returnMessage = Request.CreateResponse(responseMessage.StatusCode);
returnMessage.ReasonPhrase = responseMessage.ReasonPhrase;
returnMessage.Content = CopyContentStream(responseMessage);
//Copies all safe HTTP headers (mainly content) to the response
CopyHeaders(returnMessage, responseMessage);
}
private static PushStreamContent CopyContentStream(HttpResponseMessage sourceContent)
{
var content = new PushStreamContent(async (stream, context, transport) =>
await sourceContent.Content.ReadAsStreamAsync()
.ContinueWith(t1 => t1.Result.CopyToAsync(stream)
.ContinueWith(t2 => stream.Dispose())));
return content;
}
Ошибка, возникающая с перерывами:
Асинхронный модуль или обработчик завершен, пока асинхронная операция еще не выполнена.
Эта ошибка обычно возникает при первых нескольких запросах к прокси-приложениям, после чего ошибка больше не отображается.
Visual Studio никогда не ловит Исключение при броске. Но ошибка может быть обнаружена в событии Global.asax Application_Error. К сожалению, в Exception нет трассировки стека.
Прокси-приложения размещаются в ролях Azure Web.
Любая помощь, идентифицирующая виновника, будет оценена.