用于消息压缩的WCF绑定扩展

时间:2011-03-01 08:37:53

标签: wcf binding compression

我正在尝试将消息压缩添加到我的WCF服务中,但我有点卡住......

到目前为止,我有:

  1. MessageEncoder的实现:

    public class CompressionEncoder : MessageEncoder  
    {
    
        public CompressionEncoderFactory _factory;  
        public const string GZipContentType = "application/x-gzip";
    
        public override string ContentType
        {
            get
            {
                return GZipContentType;
            }
        }
    
        public override string MediaType
        {
            get { return ContentType; }
        }
    
        public override MessageVersion MessageVersion
        {
            get { return _factory.MessageVersion; }
        }
    
        public CompressionEncoder(CompressionEncoderFactory factory)
        {
            _factory = factory;
        }
    
        public override Message ReadMessage(Stream stream, int maxSizeOfHeaders,     string contentType)
        {
            var decompressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Decompress, false);
            XmlReader reader = XmlReader.Create(decompressedStream);
            Message msg = Message.CreateMessage(reader, maxSizeOfHeaders, _factory.MessageVersion);
            msg.Properties.Encoder = this;
            return msg;
        }
    
        public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
        {
            MemoryStream stream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count);
            GZipStream decompressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Decompress);
            return ReadMessage(decompressedStream, int.MaxValue);
        }
    
        public override void WriteMessage(Message message, Stream stream)
        {
            GZipStream compressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Compress, true);
            XmlWriter writer = XmlWriter.Create(compressedStream);
            message.WriteMessage(writer);
        }
    
        public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
        {
            MemoryStream stream = new MemoryStream();
            GZipStream compressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Compress, true);
            XmlWriter writer = XmlWriter.Create(compressedStream);
            message.WriteMessage(writer);
            writer.Close();
    
            int messageLength = (int)compressedStream.Length;
            byte[] messageBytes = new byte[messageLength];
           compressedStream.Read(messageBytes, 0, messageLength);
    
            int totalLength = messageLength + messageOffset;
            byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
            Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
    
            ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
            return byteArray;
        }
    
    }
    
  2. MessageEncoderFactory的实现:

    public class CompressionEncoderFactory : MessageEncoderFactory
    {
        CompressionMessageEncodingBindingElement _element;
    
        public CompressionEncoderFactory(CompressionMessageEncodingBindingElement element)
        {
            _element = element;
        }
    
        public override MessageEncoder Encoder
        {
            get { return new CompressionEncoder(this); }
        }
    
        public override MessageVersion MessageVersion
        {
            get { return _element.MessageVersion; }
        }
    }
    
  3. MessageEncodingBindingElement的实现:

    public sealed class CompressionMessageEncodingBindingElement : MessageEncodingBindingElement 
    {
        MessageVersion _messageVersion = MessageVersion.None;
    
        public override MessageEncoderFactory CreateMessageEncoderFactory()
        {
            return new CompressionEncoderFactory(this);
        }
    
        public override MessageVersion MessageVersion
        {
            get
            {
                return _messageVersion;
            }
            set
            {
                _messageVersion = value;
            }
        }
    
        public override BindingElement Clone()
        {
            return new CompressionMessageEncodingBindingElement();
        }
    }
    
  4. BindingElementExtensionElement的实现:

    public class CompressionBindingElementExtensionElement : BindingElementExtensionElement
    {
        public override Type BindingElementType
        {
            get { return typeof(CompressionMessageEncodingBindingElement); }
        }
    
        protected override System.ServiceModel.Channels.BindingElement      CreateBindingElement()
        {
            return new CompressionMessageEncodingBindingElement();
        }
    }
    
  5. 在web.config中我添加了这个:

    <service name="MyService">
        <endpoint address="" binding="customBinding" bindingConfiguration="CompressionBinding" contract="IMyService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
    ...
    <bindings>
      <customBinding>
        <binding name="CompressionBinding">
          <messageCompression />
          <httpTransport authenticationScheme="Anonymous"></httpTransport>
        </binding>
      </customBinding>
    </bindings>
    ...
    <extensions>
      <bindingElementExtensions>
        <add name="messageCompression" type="MyNamespace.CompressionBindingElementExtensionElement, MyNamespace" />
      </bindingElementExtensions>
    </extensions>
    

  6. 但是当我运行客户端并调用一些服务代码时,我收到以下错误:

    The message version of the outgoing message (EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)) does not match that of the encoder (Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)). Make sure the binding is configured with the same version as the message.
    

    我做错了什么?

1 个答案:

答案 0 :(得分:0)

尝试在(3.)处更改MessageVersion _messageVersion = MessageVersion.Soap12WSAddressing10;。 查看Microsoft技术示例“TechnologySamples \ Extensibility \ MessageEncoder \ Compression \”。

相关问题