Question

Je dispose actuellement d'un site de téléchargement pour mon école basé sur .net. Nous proposons tout ce que vous souhaitez télécharger, qu'il s'agisse d'antivirus, d'autocad, de spss, de bureautique ou d'un grand nombre d'applications volumineuses. Il est actuellement configuré pour les traiter de 1 à 2 manières; Tout ce qui dépasse 800 Mo est directement accessible via un site Web distinct, tandis que moins de 800 Mo sont sécurisés derrière du code .net en utilisant un flux de fichiers pour le transmettre à l'utilisateur par tranche de 10 000 octets. J'ai toutes sortes de problèmes avec l'alimentation des téléchargements de cette façon ... J'aimerais pouvoir sécuriser les téléchargements volumineux, mais le site .net ne peut tout simplement pas le gérer, et les fichiers plus petits échouent souvent. Existe-t-il une meilleure approche à cet égard?

modifier - Je voulais simplement savoir comment j'ai finalement résolu ce problème: j'ai fini par ajouter mon répertoire de téléchargement en tant que répertoire virtuel dans iis et j'ai spécifié un gestionnaire http personnalisé. Le gestionnaire a saisi le nom de fichier de la demande et a vérifié les autorisations correspondantes, puis a redirigé les utilisateurs vers une page d'erreur / de connexion ou laissé le téléchargement se poursuivre. Je n’éprouve aucun problème avec cette solution, et cela fait probablement sept mois que je travaille dessus, servant des fichiers de plusieurs concerts.

Était-ce utile?

La solution

J'ai deux recommandations:

  • Augmentez la taille de la mémoire tampon afin qu'il y ait moins d'itérations

ET / OU

  • N'appelez pas IsClientConnected à chaque itération.

La raison en est que, selon les Consignes de Microsoft :

Response.IsClientConnected a certains coûts, utilisez-le donc uniquement avant une opération prenant au moins 500 millisecondes (c'est long si vous essayez de maintenir un débit de plusieurs dizaines de pages par seconde). En règle générale, ne l'appelez pas à chaque itération d'une boucle serrée

Autres conseils

Si vous rencontrez des problèmes de performances et livrez des fichiers existants sur le système de fichiers (par opposition à une base de données), utilisez la Fonction HttpResponse.TransmitFile .

En ce qui concerne les échecs, vous avez probablement un bogue. Si vous postez le code, la réponse sera peut-être meilleure.

Regardez dans bit torrent. Il est conçu spécifiquement pour ce genre de chose et est assez flexible.

Ce qui ne va pas avec l’utilisation d’un serveur Web robuste (comme Apache) et l’autorisant à gérer les fichiers. Tout comme vous séparez maintenant des fichiers plus volumineux sur un serveur Web, pourquoi ne pas également traiter les fichiers plus petits de la même manière?

Y a-t-il des exigences cachées pour empêcher cela?

Ok, voici à quoi ça ressemble actuellement ...

    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");
    }
}

Il existe de nombreuses restrictions de licence. Par exemple, nous avons un contrat de licence Office 2007 qui stipule que tout le personnel technique sur le campus peut télécharger et installer Office, mais pas les étudiants. Donc, nous ne laissons pas les étudiants le télécharger. Notre solution consistait donc à masquer ces téléchargements derrière .net.

Amazon S3 semble idéal pour ce dont vous avez besoin, mais il s’agit d’un service commercial et les fichiers sont servis à partir de leurs serveurs.

Vous devriez essayer de contacter amazon et demander des prix académiques. Même s'ils n'en ont pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top