Welcome

首页 / 软件开发 / WCF / WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(上篇)

WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(上篇)2012-11-07 博客园 Artech消息作为WCF进行通信的唯一媒介,最终需要通过写入传输层进行传递。而对消息进行传输的一个前提或者是一项必不可少的工作是对消息进行相应的编码。WCF提供了一系列可供选择的编码方式,它们分别在互操作和性能各具优势。在本篇文章我们将对各种编码方式进行消息的讨论。

从互操作性的角度来看,编码方法很大程度上决定了跨平台支持的能力。有的编码方式是平台无关的,有的则仅限于某种特定的平台。WCF提供了3种典型的编码方式:Binary、Text和MTOM。Binrary以二进制的方式进行消息的编码,但是仅限于.NET平台之间的通信;Text则提供平台无关的基于文本的编码方式。MTOM编码基于WS-MTOM规范,对于改善大规模二进制数据在SOAP消息的传输性能具有重大的意义,既然该编码方式遵循相应的规范,无疑这也是一种跨平台的编码方式。

在正式介绍WCF消息编码之前,我们很有必要了解如下几个实现编码的核心对象:XmlDictionary、XmlDictionary和XmlDIctionaryWriter。

一、XmlDictionary

XmlDictionary,顾名思义,它是一个字典,它是从事编码和解码双方共享的一份“词汇表”。这样的说法可能有点抽象,我们不妨做一个类比。比如我说“WCF是.NET平台下基于SOA的消息通信框架”,对于各位读者来说,这句话很好理解。如果我向另一个对计算机一窍不通的人说这句话,毫无疑问,对方是无论如何不能理解的。读者和我之间之所以能够通过这样的语言进行交流,是因为我们之间具有相似的知识背景,在我们之间共享相同的词汇表,对每个单词的含义具有一致的理解。而别人不能理解,是在于我和他之间的信息不对称,如果要使它能都理解,我必须用他所能理解的方式进行交流,在这种情形之下,我可能要花很多文字对这句话的一些术语进行详细的解释,比如什么是.NET平台,什么是SOA,什么又是通信框架。所以,交流的前提是双方具有相同的“词汇表”,双方就某个主题共享越多的“词汇”,交流就越容易,你说的话将越简洁。

数据的编码也像我们日常的沟通和交流一样,编码的一方是“说”的一方,解码的一方是“听”的一方。说的一方按照它所掌握的“词汇表”对信息进行编码,对方只有具有相同的“词汇表”才能正常地解码。如果这个“词汇表”越详尽,编码后的内容容量就越小。内容的浓缩意味着什么?意味着网络流量的减少,意味着为你节省更多的带宽。而XmlDictionary就是这样的一个词汇表。

XmlDictionary定义在System.Xml命名空间下,它是System.Xml.XmlDictionaryString的集合。XmlDictionaryString相当于一个KeyValuePair<int,string>对象,是一个键-值对,键和值的类型为int和string。下面是XmlDictionaryString和XmlDictionary的定义。

 1: public class XmlDictionaryString
2: {
3: //其他成员
4: public XmlDictionaryString(IXmlDictionary dictionary, string value, int key);
5: public IXmlDictionary Dictionary { get; }
6: public static XmlDictionaryString Empty { get; }
7: public int Key { get; }
8: public string Value { get; }
9:
10: }
1: public class XmlDictionary : IXmlDictionary
2: {
3:
4: //其他成员
5: public XmlDictionary();
6: public XmlDictionary(int capacity);
7: public virtual XmlDictionaryString Add(string value);
8:
9: public virtual bool TryLookup(int key, out XmlDictionaryString result);
10: public virtual bool TryLookup(string value, out XmlDictionaryString result);
11: public virtual bool TryLookup(XmlDictionaryString value, out XmlDictionaryString result);
12: }
通过下面的代码,创建了一个XmlDictionary对象,通过Add方法添加了3个XmlDictionaryString。严格说来XmlDictionary并不是一个集合对象,因为它没有实现IEnumerable接口。通过Add方法你只能指定XmlDictionaryString的Value,Key的值会以自增长的方式自动赋上。所以Customer、Name、Company 3个元素的Key分别为0,1,2,这可以从最终输出结果中看出来。

 1: IList<XmlDictionaryString> dictionaryStringList = new List<XmlDictionaryString>();
2: XmlDictionary dictionary = new XmlDictionary();
3: dictionaryStringList.Add(dictionary.Add("Customer"));
4: dictionaryStringList.Add(dictionary.Add("Name"));
5: dictionaryStringList.Add(dictionary.Add("Company"));
6: foreach (XmlDictionaryString dictionaryString in dictionaryStringList)
7: {
8: Console.WriteLine("Key:{0} Value:{1}", dictionaryString.Key, dictionaryString.Value);
9: }
输出结果:

 1: Key:0Value:Customer
2: Key:1Value:Name
3: Key:2Value:Company