Compresión GZip con WCF alojado en IIS7
iis-7 http-compression (8)
El tipo de mime es más probable Application/octet-stream
Todos, en lo que a mí respecta, la pregunta se encuentra en EDIT 2. Aunque es solo una solución parcial al lado IIS del problema, es lo que estaba buscando.
Así que voy a agregar mi consulta al pequeño océano de preguntas sobre el tema.
Estoy tratando de habilitar la compresión GZip en grandes respuestas de jabón de un servicio WCF. Hasta ahora, he seguido las instrucciones here y en una variedad de otros lugares para habilitar la compresión dinámica en IIS. Aquí está mi sección dynamicTypes de la aplicaciónHost.config:
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="application/xop+xml" enabled="true" />
<add mimeType="application/soap+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
Y también:
<urlCompression doDynamicCompression="true" doStaticCompression="true" />
Aunque no tengo muy claro por qué es necesario.
Lanzó algunos tipos de mime adicionales allí por si acaso. Implementé IClientMessageInspector para agregar Accept-Encoding: gzip, deflate a HttpRequests de mi cliente. Aquí hay un ejemplo de un encabezado de solicitud tomado de fiddler:
POST http://[omitted]/TestMtomService/TextService.svc HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Accept-Encoding: gzip, deflate
Host: [omitted]
Content-Length: 542
Expect: 100-continue
Ahora, esto no funciona. Simplemente no hay compresión, sin importar el tamaño del mensaje (intentado hasta 1.5Mb). He visto esta publicación , pero no he encontrado una excepción como él describe, así que no he probado la implementación de CodeProject que él propone. También he visto muchas otras implementaciones que se supone deben hacer que esto funcione, pero no puede encontrarles sentido (por ejemplo, el codificador GZip de msdn ). ¿Por qué tendría que implementar el codificador o la solución del proyecto de código? ¿No debería IIS encargarse de la compresión?
Entonces, ¿qué más debo hacer para que esto funcione?
Joni
EDITAR: Pensé que valía la pena publicar los enlaces de WCF, aunque no estoy seguro de si son relevantes (estos son del cliente):
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsTextBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="5000000" maxReceivedMessageSize="5000000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="5000000"
maxArrayLength="5000000" maxBytesPerRead="5000000" maxNameTableCharCount="5000000" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="None" negotiateServiceCredential="false"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
<client>
<endpoint address="http://[omitted]/TestMtomService/TextService.svc"
binding="wsHttpBinding" bindingConfiguration="WsTextBinding" behaviorConfiguration="GzipCompressionBehavior"
contract="TestMtomModel.ICustomerService" name="WsTextEndpoint">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="GzipCompressionBehavior">
<gzipCompression />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="gzipCompression"
type="TestMtomModel.Behavior.GzipCompressionBehaviorExtensionElement, TestMtomModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</binding>
</wsHttpBinding>
</bindings>
EDIT 2: Bueno para cualquier otra persona en esta misteriosa situación, tengo una solución parcial. Es decir, logré que IIS7 al menos comprima los mensajes de jabón del servicio (aunque ahora recibo una excepción en el cliente, pero para eso se han publicado varias soluciones). El problema era que el DynamicCompressionModule no estaba instalado en mi servidor. "Instalarlo" en realidad, para mí, significa simplemente agregar esta línea a la sección applicationHost.config:
<add name="DynamicCompressionModule" image="%windir%/System32/inetsrv/compdyn.dll" />
(Suponiendo que el dll existe en ese directorio, que en mi caso sí lo hizo.) Y luego agregando el módulo a través de la sección Módulos de IIS7 para el sitio web o servidor.
Esta es básicamente la misma respuesta que @marko, con pasos detallados. Este es un tema frustrante cada vez que lo reviso, así que quería esbozar todo lo que tengo que hacer para que funcione.
Lo primero es lo primero que querrá utilizar .NET 4 en IIS7. Esto se debe a que no fue hasta .NET 4 que WCF fue capaz de descomprimir automáticamente las corrientes gzip. Los detalles de esto se describen en '' Qué es nuevo en WCF 4 '' (algunos comentarios útiles en comentarios).
Lo hemos hecho más fácil al usar HTTP al permitir que el cliente negocie automáticamente usando gzip o deflate streams comprimidos y luego los descomprima automáticamente.
Segundo, asegúrese de haber habilitado el módulo de compresión dinámica en IIS. Es posible que deba ir a ''Programas y características'' para instalarlo. Asegúrese de tenerlo habilitado para la aplicación web en cuestión, ya que no es una configuración global.
Ahora WPF usa la
application/soap+xml; charset=utf-8
tipo MIMEapplication/soap+xml; charset=utf-8
application/soap+xml; charset=utf-8
para la transmisión HTTP (al menos con wsHttpBinding lo hace). Por defecto, NO está clasificado como un tipo dinámico, por lo que debe agregarse al archivoapplicationHost.config
.Solo edite este archivo EN EL SERVIDOR: C: / Windows / System32 / Inetsrv / Config / applicationHost.config
En el nodo
<dynamicTypes>
agregue la siguiente línea (ANTES DE / LINE):<add mimeType="application/soap+xml; charset=utf-8" enabled="true" />
Reiniciar IIS
Ahora debería tener datos comprimidos, que se pueden verificar en Fiddler.
He estado luchando con esto también y no pude hacer que funcione con mi .svc aunque estaba bien con archivos .aspx en la misma aplicación. Resulta que solo funciona con basicHttpBinding y no con wsHttpBinding o con un binary customBinding codificado. Esto está bien para mí ya que el factor de compresión supera el beneficio del codificador binario (que reduce bastante el tamaño del mensaje pero no el factor de 10 que proporciona la compresión).
Intente agregar ''application / soap + xml; charset = utf-8 ''como tipo dinámico en applicationHost. Agregar esta parte del juego de caracteres me ayudó a habilitar la compresión de algunas respuestas JSON de mi controlador http.
La mejor opción es evaluar el tipo de mime específico con el que tiene problemas (por ejemplo, Fiddler) y asegurarse de que esté incorporado en applicationHost.config. Si la compresión está instalada y configurada correctamente, el seguimiento de solicitudes fallidas le informará que la compresión no se realizó con una disposición "NO_MATCHING_CONTENT_TYPE".
Mucha gente está luchando para habilitar la compresión de nivel IIS para WCF Services. Principalmente la gente está luchando con wsHttpBinding, donde basicHttpBinding se comprime de fábrica si la compresión dinámica está habilitada en IIS. No voy a entrar en cómo habilitar la compresión dinámica porque está cubierta en muchas publicaciones diferentes, solo busque "iis compression application / soap + xml" . Como se mencionó anteriormente, si ha configurado todo correctamente, debería poder ver las respuestas de WCF comprimidas con Content-Encoding: gzip en el encabezado de respuesta. Sugiero usar Fiddler para rastrear tu solicitud / respuesta. Esta fue mi (muchas otras) experiencias con basicHttpBinding. La pregunta entonces es ¿por qué no funciona con wsHttpBinding? Sin dudas, ya has leído que es porque Content-Type es diferente entre esos dos enlaces. basicHttpBinding utiliza Content-Type: text / xml; charset = utf-8 donde wsHttpBinding utiliza Content-Type: application / soap + xml; charset = utf-8 . El primero está cubierto por la configuración predeterminada de IIS applicationHost.config en dynamicTypes. El último no es. Probablemente haya leído que necesita agregar este mimeType adicional y reiniciar IIS para solucionarlo. Esto funciona para algunas personas, sin embargo, no sirve para muchos. Algunos declaran que simplemente no es compatible con wsHttpBinding. Aquí está el problema Hay potencialmente dos archivos applicationHost.config:
C:/Windows/System32/inetsrv/config
C:/Windows/SysWOW64/inetsrv/Config
System32 es el de 64 bits y es el utilizado por su instalación de IIS. ¡Este también es el que modificó para agregar el mimeType adicional, o eso creyó!
no se puede editar manualmente applicationhost.config - DEBE LEER
Resulta que si usas una aplicación de 32 bits como Notepad ++, lo que terminas modificando es el archivo en la carpeta SysWOW64. Esto es completamente transparente para ti. Si utiliza la aplicación de Bloc de notas habitual, notará que el mimeType que ha agregado no está realmente en el archivo que se encuentra en la carpeta System32, sino que se agregó mágicamente a la carpeta SysWOW64, aunque nunca lo haya navegado. carpeta para comenzar. Espero que esto te ahorre muchas horas de dolor.
Si alguna vez alguien se topa con esto al hospedarse en Azure como WebApp, puede configurar el applicationHost.config usando una extensión llamada "IIS Manager" usando el portal azure en "Extensions". Más información sobre la extensión en sí https://github.com/shibayan/IISManager
Solo para alguien más que pueda mirar en el futuro. Actualizamos a Windows 2012 Server e IIS 8. Los viejos mimetypets de compresión de configuración que funcionaban para IIS 7 no funcionaban para IIS 8.
Entonces, intenté un par de sugerencias aquí, pero nada funcionó. Terminé añadiendo esto a httpcompression dynamictypes: multipart/*
y luego la compresión gzip estaba funcionando nuevamente.
Espero que esto ayude a alguien más.