Pregunta

Actualmente tengo un sitio de descarga para mi escuela basado en .net. Ofrecemos cualquier cosa, desde antivirus, autocad, spss, office y varias aplicaciones grandes para que los estudiantes las descarguen. Actualmente está configurado para manejarlos de 1 a 2 formas; Se puede acceder directamente a cualquier elemento de más de 800 megas a través de un sitio web separado, mientras que a menos de 800 megas está protegido con código .net utilizando un flujo de archivos para alimentarlo al usuario en trozos de 10.000 bytes. Tengo todo tipo de problemas con las descargas de alimentación de esta manera ... Me gustaría poder asegurar las descargas grandes, pero el sitio .net simplemente no puede manejarlo, y los archivos más pequeños a menudo fallan. ¿Hay un mejor enfoque para esto?

edit - Solo quería actualizar cómo finalmente resolví esto: terminé agregando mi directorio de descargas como un directorio virtual en iis y especifiqué un controlador http personalizado. El controlador tomó el nombre del archivo de la solicitud y verificó los permisos basados ??en eso, luego redirigió a los usuarios a una página de error / inicio de sesión o dejó que la descarga continuara. No he tenido problemas con esta solución, y he estado en ella probablemente durante 7 meses, sirviendo archivos de varios conciertos en tamaño.

¿Fue útil?

Solución

Tengo dos recomendaciones:

  • Aumente el tamaño del búfer para que haya menos iteraciones

Y / O

  • No llame a IsClientConnected en cada iteración.

La razón es que de acuerdo con Directrices de Microsoft :

Response.IsClientConnected tiene algunos costos, así que solo úselo antes de una operación que tome al menos 500 milisegundos (eso es mucho tiempo si está tratando de mantener un rendimiento de docenas de páginas por segundo). Como regla general, no lo llame en cada iteración de un ciclo cerrado

Otros consejos

Si tiene problemas de rendimiento y está entregando archivos que existen en el sistema de archivos (frente a un DB), use función HttpResponse.TransmitFile .

En cuanto a las fallas, es probable que tenga un error. Si publica el código, puede obtener una mejor respuesta.

Mira en bit torrent. Está diseñado específicamente para este tipo de cosas y es bastante flexible.

¿Qué tiene de malo usar un servidor web robusto (como Apache) y dejar que se ocupe de los archivos? Del mismo modo que ahora separa los archivos más grandes en un servidor web, ¿por qué no sirve también los archivos más pequeños de la misma manera?

¿Hay algunos requisitos ocultos para evitar esto?

Ok, así es como se ve actualmente ...

    Stream iStream = null;

// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];

// Length of the file:
int length;

// Total bytes to read:
long dataToRead;

if (File.Exists(localfilename))
{
    try
    {
        // Open the file.
        iStream = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

        // Total bytes to read:
        dataToRead = iStream.Length;

        context.Response.Clear();
        context.Response.Buffer = false;
        context.Response.ContentType = "application/octet-stream";
        Int64 fileLength = iStream.Length;
        context.Response.AddHeader("Content-Length", fileLength.ToString());
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename);

        // Read the bytes.
        while (dataToRead > 0)
        {
            // Verify that the client is connected.
            if (context.Response.IsClientConnected)
            {
                // Read the data in buffer.
                length = iStream.Read(buffer, 0, 10000);

                // Write the data to the current output stream.
                context.Response.OutputStream.Write(buffer, 0, length);

                // Flush the data to the HTML output.
                context.Response.Flush();

                buffer = new Byte[10000];
                dataToRead = dataToRead - length;
            }
            else
            {
                //prevent infinite loop if user disconnects
                dataToRead = -1;
            }
        }
        iStream.Close();
        iStream.Dispose();
    }
    catch (Exception ex)
    {
        if (iStream != null)
        {
            iStream.Close();
            iStream.Dispose();
        }
        if (ex.Message.Contains("The remote host closed the connection"))
        {
            context.Server.ClearError();
            context.Trace.Warn("GetFile", "The remote host closed the connection");
        }
        else
        {
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Error occurred");
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Exception", ex);
        }
        context.Response.Redirect("default.aspx");
    }
}

Hay muchas restricciones de licencia ... por ejemplo, tenemos un acuerdo de licencia de Office 2007 que dice que cualquier personal técnico en el campus puede descargar e instalar Office, pero no los estudiantes. Entonces no dejamos que los estudiantes lo descarguen. Entonces, nuestra solución fue ocultar esas descargas detrás de .net.

Amazon S3 suena ideal para lo que necesita, pero es un servicio comercial y los archivos se sirven desde sus servidores.

Debe intentar ponerse en contacto con Amazon y solicitar precios académicos. Incluso si no tienen uno.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top