Transfert de grandes charges de données (objets sérialisés) à l'aide de wsHttp dans WCF avec sécurité des messages

J'ai un cas où j'ai besoin de transférer de grandes quantités de l'objet sérialisé graphiques (via NetDataContractSerializer) à l'aide de la WCF à l'aide de wsHttp. Je suis en utilisant le message de sécurité et que vous souhaitez continuer à le faire. Avec cette configuration je voudrais transférer objet sérialisé graphique qui peut parfois démarche autour de 300 MO ou si, mais quand j'essaie de le faire, j'ai commencé à voir une exception de type System.InsufficientMemoryException apparaissent.

Après un peu de recherche, il semble que par défaut dans WCF qui suite à un appel de service est contenue dans un seul message par défaut qui contient les données sérialisées et ces données sont mises en mémoire tampon par défaut sur le serveur jusqu'à ce que le message entier est complètement écrit. Ainsi, la mémoire de l'exception qui est causé par le fait que le serveur est en cours d'exécution hors de la mémoire de ressources qu'il est autorisé à allouer parce que le tampon est plein. Les deux principales recommandations que j'ai rencontré sont à utiliser en continu ou de segmentation pour résoudre ce problème, toutefois, il n'est pas clair pour moi ce que cela implique et si une ou l'autre solution est possible avec mon installation actuelle (wsHttp/NetDataContractSerializer/Message de Sécurité). Jusqu'à présent, je comprends que pour utiliser la diffusion de messages de sécurité ne marche pas car le message de chiffrement et de déchiffrement besoin de travailler sur l'ensemble des données et non pas une partie du message. Chunking cependant sonne comme il pourrait être possible, mais il n'est pas clair pour moi comment faire avec les autres contraintes que j'ai énumérés. Si quelqu'un pourrait donner des indications sur ce que sont les solutions disponibles et comment la mettre en œuvre, je vous en serais très reconnaissante.

Je dois ajouter que dans mon cas, je ne suis vraiment pas inquiet à propos de l'interopérabilité avec d'autres clients que nous possédons et de contrôle de chaque côté de la communication et l'utilisation de l'interface partagée modèle pour les données transférées de chaque côté. Donc je suis ouvert à toute idée qui s'adapte à l'intérieur des contraintes de l'utilisation de wsHttp avec le message de sécurité pour le transfert de graphes d'objets sérialisés à l'aide de NetDataContractSerializer et je préfère une solution où je n'ai pas changer mes services existants et les infrastructures environnantes de façon drastique.

Ressources connexes:

Je suis aussi intéressé par tout type de compression qui pourrait être fait de ces données, mais il semble que je serait probablement mieux de faire cela au niveau du transport une fois que je peux transition .NET 4.0 afin que le client sera automatiquement en charge le gzip-têtes si je comprends correctement.

Mise à jour (2010-06-29):

Un peu d'histoire sur la façon dont j'ai tiré à la conclusion que la mémoire tampon de message trop grande était la cause de mon problème. À l'origine, j'ai vu le CommunicationException ci-dessous lors des tests.

La connexion sous-jacente a été fermée: La connexion a été fermée de façon inattendue.

Finalement, après l'exécution de cette et en faisant encore plus de journalisation j'ai trouvé le sous-jacent InsufficientMemoryException exception qui a été à l'origine du problème avec le message spécifié.

N'a pas pu allouer une gestion de la mémoire tampon de 268435456 octets. La quantité de mémoire disponible peut être faible.

À l'origine de la méthode suivante.

Système.ServiceModel.Diagnostics.Utilitaire.AllocateByteArray(taille Int32)

Donc dans otherwords l'échec est venu de l'allocation de la matrice. Lors de l'écriture les mêmes données sérialisées sur le disque, il prend place autour de 146MB et si je l'ai coupé de moitié puis-je arrêter l'obtention de l'erreur cependant, je n'ai pas creusé plus le seuil spécifique qui brise mon tampon et si elle spécifique à mon système ou pas.

Mise à jour (2010-12-06):

Je suppose qu'à ce stade, je suis à la recherche pour certains clarifcation pour la suite. Ma compréhension est que, par défaut, avec WCF wsHttp avec le message de sécurité que l'ensemble d'un message (généralement de l'ensemble de données, je suis de retour) doit être mis en mémoire tampon sur le serveur avant que la réponse est envoyée au client et donc la cause de mes problèmes.

Solutions possibles:

  • Limitant la taille des données En utilisant une certaine forme de compression, encodage, ou la limitation des données réelles retournés à l'aide d'une sorte de pagination comme méthode afin d'éviter de consommer de la capacité maximale de la sortie de la mémoire tampon.
  • Streaming - Permet de grandes quantités de données pour être envoyé par la WCF en continu de la mode mais ce n'est pas compatible avec wsHttp ou MessageSecurity depuis ces techniques nécessitent la mise en mémoire tampon toutes les données.
  • Chunking Canal Permet aux données d'être divisé en plusieurs messages, mais à ce point, je ne suis pas sûr de les contraintes sur le contrat de service de conception et de savoir si je peux encore utiliser wsHttp avec le message de liaison.

De limiter les données que je peux retourner ne fonctionne que jusqu'à un certain point et, comme avec l'option de diffusion de ces options nécessitent le codage d'un lot de la baisse du niveau de travail à l'extérieur de la WCF les appels de service. Donc je suppose que j'ai besoin de savoir, c'est si possible de la mise en œuvre de la segmentation du canal côté les grands problèmes de message en permettant à un ensemble unique de données pour être fractionnée en plusieurs messages sur le serveur et ensuite rassemblés sur le client de telle manière que je n'ai pas à changer l'interface, la forme de contrats de services existants et de façon à ce que le processus est assez bien caché, le client et la partie serveur de chaque service de la mise en œuvre, tout en utilisant la sécurité des messages et wsHttp. Si le chunking-canal va m'obliger à re-écrire ma de contrats de service à exposer les ruisseaux, alors je ne vois pas en quoi cela est vraiment différent de la solution de diffusion. Si quelqu'un peut il vous suffit de répondre à ces questions pour moi, je vais remettre de l'abondance et de la marquer comme réponse.

source d'informationauteur jpierson