技术开发 频道

为数据瘦身 打造定制的WCF编码器

  若要使用消息编码器,我们需要调用ReadMessage和WriteMessage方法来读写流或者字节数组。因此,若要编写一个定制的编码器,要么扩展现有消息编码器,或者为一些Message基本类如MessageEncoder、MessageEncoderFactory和MessageEncodingBindingElement提供一个定制的实现:

  ·MessageEncoder使用WriteMessage方法将传输的消息序列化,并使用ReadMessage方法将入站的消息解序列化。为了插入一个定制的实现,我们必须将这两个方法覆盖掉。 一般地,它们位于传输信道中,不过也可以用于信道堆栈的其他地方。

  ·MessageEncoderFactory规定用于配置这些服务的信息。我们需要覆盖这个抽象类中的CreateMessageEncoderFactory 方法。

  ·MessageEncodingBindingElement支持向捆绑元素添加编码。

  为了把定制的编码器完全地集成到WCF服务中,我们还必须确保能够完全控制编码器本身,包括:

  ·一个开关,用于启用/停用对WCF请求的压缩,最好放到客户端配置中。

  ·一个开关,用于启用/禁用对WCF响应的压缩,最好放到服务器端配置中。

  ·一个键,用于指示定制的压缩编码器。

  ·扩展WCF以支持各种各样的基于SOAP的交互。例如,我们可能需要指出各种客户端,包括仍然使用.NET框架1.1的客户端。

  ·一个简单机制,用以确定入站的数据是否是压缩后的,以便快速响应并避免错误。

  2.创建一个定制的编码器

  首先,我们需要创建一个定制的MessageEncoderFactory,它能创建我们的定制的编码器对象,它需要:

  ·一个被覆盖的编码器对象

  ·一个被覆盖的消息版本

  包含一个从CustomMessageEncoder工厂创建的名为CustomEncoderFactory的样本类。我们需要将该编码器标记为一个单独的CustomMessageEncoder工厂对象。

  为了创建一个CustomEncoderFactory实例,需要传入两个新的东西:一个EncodeMode枚举值以及一个EnableCompression变量:

  ·EncodeMode是一个可根据配置值动态改变编码格式,并且无需知道任何特殊的编码器的深入知识就可以编写压缩/解压缩逻辑的枚举值。它支持各种压缩类型,包括None、Deflate、Gzip,同时,我们还可以添加更多定制的压缩编码器格式:

   /// <summary>
  
/// Compression Encoder formats. Add custom encoders such as
  
/// ICSharpLib, 7z, rar
  
/// </summary>
   public enum CompressionEncoder
   {
      None,
      Deflate,
      GZip
   }

  ·EnableCompression是一个布尔开关值,通过它可以启用或者禁用压缩处理。

  接下来,我们需要创建一个CustomEncoder,以实现抽象类MessageEncoder,具体代码如清单2所示。清单2的示例代码实现了IsDataCompressed方法,用以确定数据是否已经压缩。对于Gzip,可以使用“幻码”值来确定数据是否经过压缩处理。

  就像前面提到的那样,这个定制的编码器的编码过程是在ReadMessage和WriteMessage方法中进行的。所以,我们还需要覆盖ContentType属性来交付不同的内容类型。枚举类型的CompressionEncoder变量值决定了运行时的内容类型。

  然后,我们需要创建一个CustomMessageEncodingBinding元素,以便规定可配置的定制属性,在本例中它包含EnableCompression、CompressionEncoder 和捆绑元素。

  最后,我们需要创建一个CustomMessageEncodingElement元素,它派生自BindingElementExtensionElement类。

0
相关文章