赞助商
MTOM消息优化传输机制主要应用于大量数据的传输,很多文章中也直接得出结论:使用MTOM文件传输效率高。为什么MTOM的数据传输效率会比别的方式要高?MTOM真的如此完美吗,它有什么不足?什么情况下使用MTOM?这些疑问,本文WSE3.0构建Web服务安全系列文章的第4节:MTOM消息优化传输机制和文件上传、下载--将为您一一解答。

本节结构为
1.MTOM基础概念
2.WSE3.0工具配置MTOM
3.代码实现与分析
4.总结。
最后附上实现代码供大家参考。

    WSE3.0中引入MTOM机制,给我们借助WSE框架实现大量数据的交互带来显著的益处。在WSE 3.0中,我们可以使用MTOM用于服务器端和客户端传递消息,另外的好处就是,WSE 3.0M允我们在传递大数据量时使用WSE 3.0消息层的安全性机制,借助WSE3.0的安全框架,我们不仅可以验证用户的合法性,还可以对消息进行加密,不仅能够保证数据的安全,还可以实现大数据量的高效传输。
 
1.【MTOM基础概念】

  提到MTOM消息优化传输机制,通常的实验结果是使用MTOM传输数据会提高大约33%的性能。 消息传输优化机制 (MTOM) 标准允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。MTOM 消息会打包为多部分/相关 MIME 序列,放在SOAP 消息中一起传送。

    我们需要了解一些相关的概念。什么是BASE64编码、MTOM消息优化传输机制、MIME。这些对于我们理解MTOM消息优化传输机制问题非常的必要。下面就来做下介绍。

1.1【BASE64编码】

    BASE64编码 的原理很简单,其方法是,将输入数据流每次取6 bit(每bit代表1位二进制),不足6bit的补0,这样,每3个8位字节将编码为4个6位字节(3×8 → 4×6);不满4个字节的以“=”填充。其实这4个六位字节 仍然是8位,只不过高两位被设置为0。当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0~63)。

  这样就可以将3个8位字节,转换为4个字节,这4个转换的字节都可以映射到字符中。也即数据都可以使用字符编码代替。 因为转换后的字符串要比原来的多一个字节,长1/3。因此编码后的数据长度增加到4/3倍。这里也是为什么使用SOAP消息效率比MTOM低的原因。因为SOAP使用XML语言进行消息传递,XML是基于BASE64编码的语言。

1.2【MIME】

    MIME表示多用途Internet邮件扩允协议。MIME扩允了基本的面向文本的Internet邮件系统,以便可以在消息中包含二进制附件。MIME(Multipurpose Internet Mail Extentions),一般译作"多用途的网络邮件扩充协议"。顾名思义,它可以传送多媒体文件。 MIME (Multipurpose Internet Mail Extensions,多目的Internet邮件扩展)是创建用于电子邮件交换,网络文档,及企业网和Internet上的其他应用程序中的文件格式的规范。

1.3【MTOM消息优化传输】

    MTOM 全称Message Transmission Optimization Mechanism,即消息传输优化机制。它提出的模型适用于大量数据的交互情况。针对Base64编码情况带来的开销提出的解决方案。当数据量小的时候,SOAP依然使用XML进行消息的传递。

    但是在大量数据情况下,如果数据依然进行Base64编码,会带来33%的额外开销,这样的情况对于大量数据交换的情况是无法容忍的。MTOM 就是针对SOAP 消息传输的基础上提出的改进办法。对于大量数据的传递,不会进行进行Base64编码,而是直接以附件的二进制原始数据的形式封装在SOAP消息的MIME 部分,进行传输。SOAP 消息通过指向随其发送的 MIME 部分来引用二进制内容,另外包括SOAP基本的XML 数据,这些还是Base64编码。因为此模型与简单邮件协议SMTP 模型基本一致。

      MTOM通过简化大量数据的编码过程,从而提高数据的处理效率。因为SOAP消息等必要的信息,MTOM 也有一些必要的开销。MTOM仅在二进制数据元素的大小超过大约 1 KB 时,才能体现出其优势。

2.【WSE3.0工具配置MTOM】

    在WSE3.0项目中使用MTOM消息传输优化机制非常的方便,我们可以使用WSE 3.0配置工具分别为Web 服务和Client客户端设置启用MTOM,生成相应的策略文件,WSE3.0机制会根据策略对消息传输使用MTOM(也可以通过代码实现) 。

    数据使用字节流byte[]数组在客户端和服务端进行传输,简单的例子就是消息的交互和文件的上传和下载操作。本次配置基本介绍的情况也是借助WSE3.0的安全机制实现文件的安全传输。

    2.1首先使用WSE 3.0配置工具设置服务端消息传输策略。如图:
附件: 2009-3-10MTOM.gif


客户端设置为on,要求客户端使用MTOM机制进行数据传输。服务端设置为Optional,表示可选这的。此种情况即服务端会根据数据的大小决定是否启用MTOM机制进行数据传递.如果设置为Always,服务端会一直使用MTOM机制进行消息的传递。一般不推荐使用这个方式。OFF即一直不使用MTOM机制进行消息传递。64为最大附加二进制文件的个数。最后表示需要首先使用SOAP消息封装。

对应的配置文件为:
  1.     <messaging>
  2.       <mtom serverMode="optional" clientMode="On" />
  3.     </messaging>
复制代码

    2.2客户端的设置与服务端类似:
附件: 2009-3-10MTOMClient.gif


客户端配置文件的代码如下:
  1.     <messaging>
  2.       <mtom clientMode="On" serverMode="optional" />
  3.     </messaging>
复制代码

3.【代码实现与分析】
    进行完毕配置以后我们来具体进入代码的开发阶段。这里给出了使用MTOM上传照片的例子,一个使用了证书加密图片上传。先给出服务端的实现,包括两个服务类:WSE3MTOMService和WSE3MTOMSecureService。方法都是二进制字节数据流的传递。

3.1WSE3MTOMService直接实现基于MTOM机制的图片上传和下载方法,具体实现如下:

  1. //WSE 3.0 Samples中的MTOM示例演示了:不加密上传、下载文件、
  2. [WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]
  3. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  4. public class WSE3MTOMService : System.Web.Services.WebService
  5. {
  6.     public WSE3MTOMService()
  7.     {
  8.     }
  9.     //此方法返回不加密的字节数组,下载文件
  10.     [WebMethod]
  11.     public byte[] DownLoadFile(string fileName)
  12.     {
  13.         byte[] file = new byte[1024];
  14.         String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
  15.         file = File.ReadAllBytes(filePath);
  16.         return file;
  17.     }
  18.     //上传文件,传回2进制数据
  19.     [WebMethod]
  20.     public void UpLoadFile(byte[] file)
  21.     {
  22.         String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + "FrankXuLei.gif";
  23.         if (File.Exists(filePath))
  24.             File.Delete(filePath);
  25.         File.WriteAllBytes(filePath, file);
  26.     }
  27. }
复制代码

3.2WSE3MTOMSecureService定义了一个文件下载的方法。具体如下:

  1. //WSE 3.0 Samples中的MTOM示例演示了:加密上传、下载文件、
  2. [WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]
  3. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  4. //Returns binary data secured via the ServerPolicy in the wse3policyCache.config policy file
  5. [Policy("ServerPolicy")]
  6. public class WSE3MTOMSecureService : System.Web.Services.WebService
  7. {
  8.     public WSE3MTOMSecureService()
  9.     {
  10.     }
  11.     //T通过服务端 X509 证书加密
  12.     // MTOM可以使用WS-Security安全协议.
  13.     [WebMethod]
  14.     public byte[] DownLoadFileWithSecurity(string fileName)
  15.     {
  16.         byte[] file = null;
  17.         String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
  18.         file = File.ReadAllBytes(filePath);//从文件里读取字节流
  19.         return file;
  20.     }
  21. }
复制代码

3.3客户端建立控制台应用程序,添加对Web服务的引用。实例化连个代理服务类,进行文件的上传和下载。具体代码如下:

  1. //直接进行数据传输,不需要加密
  2.         public void DownLoadFile(String fileName)
  3.         {
  4.             //实例化服务代理类
  5.             WSE3MTOMServiceWse serviceproxy = new WSE3MTOMServiceWse();
  6.             //or alternatively set the RequireMtom property on the proxy
  7.             //serviceproxy.RequireMtom = true;
  8.             //获取文件二进制字节流
  9.             byte[] loadFile = serviceproxy.DownLoadFile(fileName);
  10.             //打印数据信息
  11.             Console.WriteLine("File Name: {0}", fileName);
  12.             Console.WriteLine("File has been downloaded without security sucessfully from Server: {0}", loadFile.Length);
  13.             //保存文件
  14.             String filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;
  15.             Console.WriteLine("");
  16.             if (File.Exists(filePath))
  17.                 File.Delete(filePath);
  18.             File.WriteAllBytes(filePath, loadFile);
  19.         }
  20.         //安全方式下载文件
  21.         public void DownLoadFileSecure(String fileName)
  22.         {
  23.            
  24.             WSE3MTOMSecureServiceWse serviceproxy = new WSE3MTOMSecureServiceWse();
  25.             //Set anonymousForCertificateSecurity policy assertion when calling
  26.             //this secure service
  27.             serviceproxy.SetPolicy("ClientPolicy");
  28.             byte[] loadFile = serviceproxy.DownLoadFileWithSecurity(fileName);
  29.             //打印数据信息
  30.             Console.WriteLine("File Name: {0}", fileName);
  31.             Console.WriteLine("File has been downloaded with security sucessfully from Server: {0}", loadFile.Length);
  32.             //保存文件
  33.             String filePath = AppDomain.CurrentDomain.BaseDirectory + "Secure_"+ fileName;
  34.             Console.WriteLine("");
  35.             if (File.Exists(filePath))
  36.                 File.Delete(filePath);
  37.                 File.WriteAllBytes(filePath, loadFile);
  38.         }
  39.         //测试非加密安全上传文件
  40.         public void UpLoadFile(String fileName)
  41.         {
  42.             String filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;
  43.             //实例化服务代理
  44.             WSE3MTOMServiceWse serviceproxy = new WSE3MTOMServiceWse();
  45.             //读取文件数据
  46.             byte[] upFile = File.ReadAllBytes(filePath);
  47.             //调用方法传输数据
  48.             serviceproxy.UpLoadFile(upFile);
  49.             //输出上传文件信息
  50.             Console.WriteLine("File Name: {0}", fileName);
  51.             Console.WriteLine("File has been uploaded sucessfully from Client: {0}", upFile.Length);
  52.         }
复制代码

运行结果如图:
附件: 2009-3-10MTOMResult.gif


    首先是上传一个文件到服务器端,然后进行下载操作。均显示成功。可以在程序的运行目录下找到下载的新文件。

4.【总结】

    通过以上的介绍和学习,我们知道了一下结论:
1.MTOM机制会效率提升1/3.原因:正常文本 XML 使用 Base64 对二进制数据进行编码,这要求每三个字节对应四个字符,从而使得数据的大小增加三分之一。MTOM 能够以原始字节形式传输二进制数据,这会缩短编码/解码时间并生成较小的消息。

2.使用的场合:MTOM适合大量的数据交换,通常是大量数据情况下才有优势, 如上传文档和图片,目的在于优化对较大的二进制负载的传输。

3.缺陷:对于较小的二进制负载来说,使用 MTOM 发送 SOAP 消息会产生显著的开销。

  另外提供本文的代码下载。以供大家学习参考,代码下载连接:附件: WSE3MTOM.rar 。如有意见也欢迎交流~

  Web服务驻留在IIS外,可以由系统服务、控制台程序等托管的方式比较简单,大家可以参考微软的例子,这个WCF里也有类似的寄宿宿主的概念。其实有许多相似之处。

  最后在准备《WSE3.0构建Web服务安全》系列文章的过程中,我也收获不少,也希望本系列文章能给您的学习带来一些帮助。包括我之前的 WCF 分布式开发必备知识系列 都是学习WCF分布式重要知识点的总结。并且全部给出了详细的代码实现和注释。方便大家的学习和实际项目的应用。下面我们将正式进入WCF分布式开发的学习阶段,我会继续给出系统的介绍和详细的实现代码。希望有兴趣的朋友继续关注~谢谢

1.WSE 3.0 构建 Web 服务安全(1):WSE3.0安全机制与实例开发
2.WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
3.WSE3.0构建Web服务安全(3):WSE3.0策略配置、证书、签名、与实例开发

参考资料:
1.BASE64编码基于十进制的实现方法
2.MTOM编码 MSDN


文/Frank Xu Lei  出处/博客园
赞助商
赞助商
TOP