Расширение привязки WCF для сжатия сообщений - PullRequest
0 голосов
/ 01 марта 2011

Я пытаюсь добавить сжатие сообщений в свой сервис 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>
    

Но когда я запускаю клиент и вызываю какой-то сервисный код, я получаю следующую ошибку:

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 голосов
/ 04 июня 2013

Попробуйте изменить MessageVersion _messageVersion = MessageVersion.Soap12WSAddressing10; в (3.).Посмотрите на образец технологии Microsoft "TechnologySamples \ Extensibility \ MessageEncoder \ Compression \".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...