Comment fournir de gros fichiers ASP.NET Réponse?
Je ne suis pas à la recherche d'alternative de fichier de transmission en continu de contenu
la base de données, en effet, je suis à la recherche de la racine du problème, c'était
exécutant le fichier jusqu'à IIS 6, où nous avons donné notre application en mode classique, maintenant, nous
mise à niveau de notre IIS 7 et nous sommes application en cours d'exécution de la piscine en mode pipeline et
ce problème a commencé.
J'ai un gestionnaire d'événements, où j'ai à fournir de gros fichiers à la demande du client. Et je fais face à des problèmes suivants,
Fichiers sont de taille moyenne, de 4 à 100 MO, donc permet de considérer 80 MO de téléchargement de fichier cas.
De Mise En Mémoire Tampon, Démarrage Lent
Response.BufferOutput = True;
Il en résulte un démarrage très lent de fichier, comme utilisateur télécharge et même barre de progression ne s'affiche pas jusqu'à quelques secondes, généralement de 3 à 20 secondes, la raison est derrière, IIS lit tout le fichier d'abord, détermine la longueur du contenu et ensuite commencer le transfert de fichiers. Fichier est lu dans un lecteur vidéo, et il fonctionne très très lent, mais l'iPad ne télécharge que la fraction de fichier de sorte qu'il fonctionne rapidement.
De Mise En Mémoire Tampon, Aucune Content-Length, Démarrage Rapide, Aucun Progrès N'
Reponse.BufferOutput = False;
Il en résulte démarrage immédiat, toutefois client final (typique d'un navigateur comme Chrome) ne sait pas Content-Length qu'IIS ne sais pas non plus, de sorte qu'il n'affiche pas le progrès, au lieu de cela il dit X KO téléchargé.
De mise en mémoire tampon Off, Manuel Content-Length, Démarrage Rapide, le Progrès et la Violation de Protocole
Response.BufferOutput = False;
Response.AddHeader("Content-Length", file.Length);
Cette résultats dans le bon immédiate fichier de téléchargement dans google Chrome, etc, toutefois, dans certains cas, IIS gestionnaire de résultats dans la partie "Client Distant a Fermé la Connexion d'erreur" (ce qui est très fréquent) et d'autres WebClient résultats en violation de protocole. Ce qui se passe de 5 à 10% de toutes les demandes, pas toutes les demandes.
Je suppose que ce qui se passe est, IIS ne pas envoyer quoi que ce soit disant 100 continuer quand nous ne faites pas de mise en mémoire tampon et le client peut déconnecter n'attend rien en sortie. Cependant, la lecture de fichiers à partir de la source peut prendre plus de temps, mais à côté client, j'ai augmenté délai d'attente, mais semble comme IIS timesout et n'ont aucun contrôle.
Est-il de toute façon je peux forcer Réponse à envoyer 100 de continuer et de ne pas laisser quelqu'un de fermer la connexion?
Mise à JOUR
J'ai trouvé en-têtes suivants dans Firefox/Chrome, rien ne semble inhabituel ici pour Violation de Protocole ou de la Mauvaise Tête.
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:1728000
Cache-Control:private
Content-Disposition:attachment; filename="24.jpg"
Content-Length:22355
Content-Type:image/pjpeg
Date:Wed, 07 Mar 2012 13:40:26 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Mise à JOUR 2
Tournant de Recyclage encore n'offre pas beaucoup, mais j'ai augmenté mon MaxWorkerProcess à 8 et maintenant, je reçois un moins grand nombre d'erreurs, alors avant de.
Mais sur une moyenne de 200 demandes en une seconde, de 2 à 10 requêtes échouent.., et ce qui se passe sur presque tous les deux secondes.
Mise à JOUR 3
Continue 5% des demandes à défaut avec "Le serveur a commis une violation de protocole. Section=ResponseStatusLine", j'ai un autre programme qui télécharge le contenu à partir du serveur web qui utilise le service WebClient, et qui donne cette erreur 4-5 fois par seconde, sur une moyenne, j'ai 5% de demandes de défaut. Est de toute façon il trace WebClient échec?
Problèmes Redéfini
Fichier De Zéro Octet Reçu
IIS connexion se ferme pour une raison quelconque, côté client dans le WebConfig, je reçois 0 octets pour le fichier qui n'est pas zéro octets, Nous ne hachage SHA1 vérifier, cela nous a dit que dans le serveur web IIS, aucune erreur n'est enregistrée.
Ce qui a été mon erreur, et sa résolu en utilisant Entity Framework, c'était la lecture sale (non validées lignes) que lire n'était pas dans l'étendue de transaction, de le mettre dans l'étendue de transaction a résolu ce problème.
Violation De Protocole Exception Soulevée
WebClient jette WebException dit "Le serveur a commis une violation de protocole. Section=ResponseStatusLine.
Je sais que je peux activer dangereux d'en-tête d'analyse, mais qui n'est pas le point, quand il est de mon Gestionnaire HTTP qui est de l'envoi de la bonne en-têtes, je ne sais pas pourquoi IIS est l'envoi de quelque chose de supplémentaire (vérifié sur firefox et chrome, rien d'inhabituel), cela n'arrive que 2% du temps.
Mise à JOUR 4
Trouvé sc-win32 64 erreur et j'ai lu quelque part que WebLimits pour MinBytesPerSecond doit être changé, passant de 240 à 0, encore tout est identique. Toutefois, j'ai remarqué que chaque fois que les journaux IIS 64 sc-erreur win32, IIS registres d'État HTTP 200 mais il y avait une erreur. Maintenant, je ne peux pas tourner sur l'Échec de l'enregistrement des Traces pour 200 car le résultat sera massive de fichiers.
Les deux problèmes ci-dessus ont résolu en augmentant MinBytesPerSecond et ainsi que la désactivation des Séances, j'ai ajouté réponse détaillée résumant chaque point.
- C'est pourquoi ils ont inventé le Protocole de Transfert de Fichiers 😉
- FTP 100 mo n'est pas un remplacement, Linux serveurs de téléchargement fonctionne correctement, sa IIS qui agit drôle, plus drôle la partie est IIS ferme la connexion du client et met en cause en tant que Client Distant a Fermé la Connexion !!
- Plus au point, c'est pourquoi IIS 7 a une "la diffusion en continu Lisse Module" pour diffuser de la vidéo à Silverlight et les autres clients
- Bien de ses états membres, de la bienséance chose, nos données existe dans le magasin d'objets blob dans MS SQL, et les blobs sont décomposés en 1 MO taille, ils n'existent pas en tant que fichiers dans le disque, nous savons à propos de filestream et elle se bloque pour plus de 100K de fichiers, et nous avons autour de quelques millions de fichiers, de sorte que nous devons nous en tenir à ce que nous avons. La diffusion en continu lisse et Statique Fichier modules de travail sur chaque fichier existant sur le disque, il ne fonctionne pas dans mon cas.
- Assez vrai 😉
- Il peut être intéressant de voir ce que le gestionnaire de fichier statique fourni avec IIS7 fait pour les gros fichiers et copie de la solution quelle qu'elle soit.
- Je pense, et le cas de la session, je mets à jour ma réponse, vérifiez si vous utilisez la session lorsque vous envoyez le fichier et désactivé.
Vous devez vous connecter pour publier un commentaire.
Bien que la bonne façon de livrer les gros fichiers dans IIS est l'option suivante,
Lorsque vous avez défini la longueur du contenu avec le bufferOutput est fausse, alors la raison possible de l'échec est parce que IIS essayer de comprimer le fichier que vous envoyez, et en régler la Longueur du Contenu IIS ne peut pas le modifier à l'compressé, et les erreurs de chantier (*).
Donc
keep the BufferOutput to false, and second disable the gzip from iis for the files you send
ou désactiver iis gzip pour tous les fichiers et vous gérer le gzip partie de la programmation, de maintien de gzip les fichiers que vous envoyez.Des questions similaires pour la même raison:
ASP.NET site parfois le gel et/ou en affichant bizarre de texte en haut de la page en cours de chargement, sur l'équilibrage de charge des serveurs
La Compression HTTP: Certains scripts externes/CSS de ne pas décompresser correctement de temps en temps
(*) pourquoi ne pas le changer à nouveau ? parce qu'à partir du moment où vous définir un en-tête, vous ne pouvez pas participer, sauf si vous avez activé cette option sur IIS et de prendre des cas que l'en-tête n'ont pas tous prêts envoyer au navigateur.
Suivi
Si pas gziped, la prochaine chose qu'il est venu à mon esprit, c'est que le fichier est envoyé et pour une raison quelconque, la connexion a eu du retard, et a obtenu un délai d'attente et fermé. Ainsi, vous obtenez le "Hôte Distant a Fermé La Connexion".
Cela peut être résolu en fonction de la cause:
S'il est en provenance de l'IIS, allez dans les propriétés du site web et assurez-vous de définir le plus grand "Délai d'attente de Connexion", et "Activer les connexions HTTP persistantes".
Le délai de page en changeant le web.config (vous pouvez le modifier par programmation uniquement pour une page spécifique)
Également jeter un oeil à :
http://weblogs.asp.net/aghausman/archive/2009/02/20/prevent-request-timeout-in-asp-net.aspx
Session de verrouillage
Une chose que vous devez examiner est de ne pas utiliser de session sur le dispositif que vous utilisez pour envoyer le fichier, parce que la session se verrouille à l'action ce jusqu'à la fin et si un utilisateur de prendre plus de temps pour télécharger un fichier, une seconde peut obtenir le temps.
certains relative:
appel page aspx renvoie une image de ralentir au hasard
Remplacement ASP.Net s'session entièrement
Réponse.Fonction WriteFile échoue et donne 504 gateway time-out
Ce que je voudrais faire est d'utiliser la pas si bien connu ASP.NET Réponse.TransmitFile méthode, car il est très rapide (et, éventuellement, utilise IIS cache du noyau) et prend soin de tous les en-tête de trucs. Il est basé sur le Windows non géré TransmitFile API.
Mais pour être en mesure d'utiliser cette API, vous avez besoin d'un fichier physique pour le transfert. Donc, ici, est un pseudo-code c# qui expliquent comment faire cela avec une fiction myCacheFilePath physique chemin d'accès au fichier. Il soutient également la mise en cache du client de possibilités. Bien sûr, si vous avez déjà un dossier à la main, vous n'avez pas besoin de créer du cache:
Ce bout de code fonctionne pour moi.
Il commence le flux de données pour le client immédiatement.
Il montre les progrès en cours de téléchargement.
Il ne viole pas les HTTP. Contenu de l'en-tête de Longueur est spécifiée et que le chuncked le codage de transfert n'est pas utilisé.