c# - Soporte de transmisión de solicitud de WebAPI
asp.net streaming (1)
Esa es una pregunta interesante. Trataré de hacer mi mejor esfuerzo para dar algunos consejos generales.
Pocas cosas a considerar:
1) La API web predetermina las solicitudes de los buffers, por lo que su temor a que la huella de memoria sea considerable está definitivamente justificado. Puede forzar que la API web funcione con solicitudes en un modo de transmisión continua:
public class NoBufferPolicySelector : WebHostBufferPolicySelector
{
public override bool UseBufferedInputStream(object hostContext)
{
var context = hostContext as HttpContextBase;
if (context != null)
{
if (string.Equals(context.Request.RequestContext.RouteData.Values["controller"].ToString(), "uploading", StringComparison.InvariantCultureIgnoreCase))
return false;
}
return true;
}
public override bool UseBufferedOutputStream(HttpResponseMessage response)
{
return base.UseBufferedOutputStream(response);
}
}
Y luego reemplace el servicio:
GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new NoBufferPolicySelector());
Tenga en cuenta que debido a las diferencias entre WebHost y SelfHost en este punto, dicho cambio solo es posible en WebHost. Si su punto final está autoalimentado, deberá establecer el modo de transmisión en el nivel GlobalConfig:
//requests only
selfHostConf.TransferMode = TransferMode.StreamedRequest;
//responses only
selfHostConf.TransferMode = TransferMode.StreamedResponse;
//both
selfHostConf.TransferMode = TransferMode.Streamed;
He escrito un blog sobre el manejo de archivos de gran tamaño en la API web con más detalles antes - http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/ así que con suerte lo encontrarás útil.
2) En segundo lugar, si usa HttpClient
, en .NET 4 almacena el cuerpo de las solicitudes de manera predeterminada, por lo que debería usar .NEt 4.5.
Si tiene que usar .NET 4, debe trabajar directamente con HttWebRequest
: - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowreadstreambuffering.aspx - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowwritestreambuffering.aspx
3) En cuanto a empujar los datos al cliente que definitivamente es posible si quieres hacer eso, con PushStreamContent
. Henrik tiene una breve publicación introductoria aquí: http://blogs.msdn.com/b/henrikn/archive/2012/04/23/using-cookies-with-asp-net-web-api.aspx (está basado en la Web). API RC bits por lo que es posible que tenga que ajustar algunas firmas, etc.) También escribí en mi blog acerca de empujar fragmentos de datos de transmisión aquí - http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/
EDITAR: para ver un ejemplo si PushStreamContent
en la solicitud, puede echarle un vistazo a esta solución de muestra: http://aspnet.codeplex.com/SourceControl/changeset/view/bb167f0b0013#Samples/Net45/CS/WebApi/UploadXDocumentSample/ReadMe.txt
Estoy escribiendo una aplicación ASP.NET Web API que me exige aceptar una carga de archivo y reenviar ese archivo a otro punto final HTTP.
Me preocupa que si muchos usuarios intentan cargar un archivo de 100MB cada uno (que es un caso de uso válido), entonces mi aplicación tendrá una gran huella de memoria y, dependiendo del volumen de grandes solicitudes, esta huella podría crecer y mi aplicación se debilitaría. más y morir.
Idealmente, me gustaría comenzar a transmitir el archivo al otro extremo HTTP tan pronto como el servidor web comience a recibir el archivo para reducir significativamente la carga en el servidor.
Estoy seguro de que este proceso tiene un nombre, pero no lo sé, lo que hace que la búsqueda sea bastante difícil.
He trabajado bastante con Response Streaming en la API web, pero nunca antes tuve que considerar la posibilidad de solicitar la transmisión.
Lo mejor que puedo decir es que necesito averiguar cómo:
- Comience a procesar la transmisión antes de que termine de cargarse.
- Use HttpClient para transmitir la misma solicitud para transmitir los mismos datos al otro punto final HTTP.
¿Alguien puede ofrecerme algunos consejos?