J'active la Compression dynamique
sur IIS à l'aide d'un excellent article de Scott Hanselman :
Au début de l'article, il dit que :
Du côté client, il est facile d'ajouter simplement du code comme celui-ci:
using (ServiceReference1.Srv1 client = new ServiceReference1.Srv1Client()) { var data = client.GetData(string longText, byte[] file); }
La première question est: Où dois-je ajouter le code ci-dessus?
J'utilise BasicHttpBinding code> et maintenant veuillez considérer ce code:
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
par ce code, j'appelle mon service depuis l'application cliente. Maintenant, la question est de savoir comment puis-je compresser automatiquement la demande du client (tous les paramètres) avec GZIP
pour accélérer les appels du service Web?
Merci
3 Réponses :
La demande de compression n'est pas une norme HTTP que les serveurs ou les clients comprennent. Pour y parvenir, vous devrez le faire vous-même à la fois dans le client et le serveur.
Je n'ai pas fait de développement WCF depuis un moment, mais je suis presque sûr que WCF a des moyens de le faire.
La propriété request.AutomaticDecompression se trouve sur l'objet HttpWebRequest. Je ne sais pas si vous utilisez le service WCF OData. Selon le blog de Scott Hanselman, cela devrait fonctionner pour le service WCF OData.
Je suppose que la compression n'est pas prise en charge par défaut pour BasciHttpBinding. L'idée est venue de ce blog.
Je créerais BehaviorExtensionElement, CompressionBehaviorSection comme indiqué ci-dessous.
<system.net> <webRequestModules> <remove prefix="http:"/> <add prefix="http:" type="WcfHttpCompressionEnabler.CompressibleHttpRequestCreator, WcfHttpCompressionEnabler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </webRequestModules> </system.net>
Ensuite, appliquez ce comportement sur la liaison HTTP de base.
IDispatchMessageInspector et IClientMessageInspector compresseraient / décompresseraient les données selon qu'elles soient envoyées ou reçues.
MISE À JOUR: 29 / janvier / 2019 Il y a un autre moyen que j'ai trouvé hier:
Étape 1: Si votre service est hébergé par IIS, vous pouvez activer le module de compression dynamique.
Ensuite, ajoutez le type mime pour le message SOAP dans applicationHost.config comme indiqué ci-dessous:
public class CompressibleHttpRequestCreator : IWebRequestCreate { public CompressibleHttpRequestCreator() { } WebRequest IWebRequestCreate.Create(Uri uri) { HttpWebRequest httpWebRequest = Activator.CreateInstance(typeof(HttpWebRequest), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { uri, null }, null) as HttpWebRequest; if (httpWebRequest == null) { return null; } httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; return httpWebRequest; } }
Étape 2: IWebRequestCreate personnalisé
Une fois cela fait, vous devrez faire en sorte que le WCF envoie l'en-tête "Accept Encoding" avec une requête HTTP. Vous pouvez créer un IWebRequestCreate personnalisé comme indiqué ci-dessous
<add mimeType="application/soap+xml" enabled="true" /> <add mimeType="application/soap+xml; charset=utf-8" enabled="true" /> <add mimeType="application/soap+xml; charset=ISO-8895-1" enabled="true" />
Étape 3: Modification de la configuration dans la configuration de votre client Ensuite, vous pouvez ajouter le paramètre ci-dessous dans l'app.config ou web.config de votre client:
public class MessageCompressionBehavior : IDispatchMessageInspector, IServiceBehavior, IClientMessageInspector { } public class CompressionBehaviorExtensionElement :BehaviorExtensionElement { } <extensions> <behaviorExtensions> <add name="compression" type="yournamespace.CompressionBehaviorExtensionElement, yourassembly, Version=...., Culture=neutral, PublicKeyToken=......"/> </behaviorExtensions> </extensions> <behaviors> <serviceBehavior> <compression /> </serviceBehavior> </behaviors>
La solution est expliquée sur ce blog . Il contient également un exemple de code sur ce lien.
J'espère que cela vous aidera suffisamment sur votre problème.
Ceci n'est que ma suggestion.
Vous pouvez définir votre propre ClientMessageFormatter, DispatchMessageFormatter.
ClientMessageFormatter est utilisé pour sérialiser la requête et désérialiser la réponse.
DispatchMessageFormatter est utilisé pour désérialiser la requête et sérialiser la requête.
Si vous pouviez utiliser votre propre algorithme de compression pour sérialiser et désérialiser les requêtes et réponses à l'aide de Gzip ou de deflate, le message sera plus petit.
Les deux interfaces ont des méthodes ci-dessous.
public void DeserializeRequest(Message message, object[] parameters) { } public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { } public object DeserializeReply(Message message, object[] parameters) { } public Message SerializeRequest(MessageVersion messageVersion, object[] parameters) { }
Pour utiliser vos propres ClientMessageFormatter et DispatchMessageFormatter, vous devez utiliser un EndpointBehavior.
Dans vous ApplyClientBehavior et ApplyDispatchBehavior, vous devez définir votre ClientMessageFormatter sur la propriété Formatter de ClientOperation et définir votre DispatchMessageFormatter sur DispatchMessageFormatter de la propriété de formateur.
De plus, pour activer l'algorithme de compression dynamique, vous feriez mieux de passer votre algorithme de compression à votre comportement de point final, puis le comportement transmet l'algorithme de compression à votre Clien tMessageFormatter et DispatchMessageFormatter afin qu'il puisse savoir quelle compression utiliser.
Il y a encore beaucoup de choses à faire, par exemple, comment utiliser ClientMessageFormatter et DispatchMessageFormatter par défaut de wcf pour sérialiser et désérialiser le message en combinant votre propre ClientMessageFormatter et DispatchMessageFormatter.
Comme le formateur par défaut de wcf est utilisé pour sérialiser et désérialiser la requête et la réponse, vous pouvez utiliser votre formateur pour compresser le message sur les bases de la sérialisation de wcf. Donc, avant d'utiliser votre formateur, vous devriez obtenir le formateur par défaut de wcf dans ApplyDispatchBehavior et ApplyClientBehavior de endpointbehavior.
Définissez ensuite la propriété some de votre propre formateur sur la propriété par défaut de wcf afin de pouvoir utiliser le formateur par défaut de wcf.
Semble être un double de: stackoverflow.com/questions/15680087/... . Cette réponse fonctionne-t-elle pour vous?
Non c'est différent
@Arian en quoi est-ce différent?
Consultez l'article suivant dotnetspeak.com/wcf/wcf-basichttpbinding-and-compression < / a>
Merci, mais je dois utiliser
basichttpbindning
et tout le lien ci-dessus recommandéliaison personnalisée
utilisez iis ou auto-hébergement?
Il hébergé sur IIS
@Arian Salut, avez-vous regardé qui ajouter un en-tête personnalisé avec un appel de service de savon? Je pense que ceux-ci peuvent vous aider à trouver un moyen de réaliser ce que vous recherchez: blogs.msdn.microsoft.com/wsdevsol / 2014/02/07 /… Et l'en-tête à ajouter était sur votre article: