3
votes

Activation de GZIP pour appeler le service WCF sur le client

J'active la Compression dynamique sur IIS à l'aide d'un excellent article de Scott Hanselman :

Activation de la compression dynamique (gzip, deflate) pour les flux de données WCF, OData et d'autres services personnalisés dans IIS7

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 :


0
votes

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.


0 commentaires

2
votes

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.


0 commentaires

1
votes

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.


0 commentaires