MTOM消息优化传输机制主要应用于大量数据的传输,很多文章中也直接得出结论:使用MTOM文件传输效率高。为什么MTOM的数据传输效率会比别的方式要高?MTOM真的如此完美吗,它有什么不足?什么情况下使用MTOM?这些疑问,本文WSE3.0构建Web服务安全系列文章的第4节:MTOM消息优化传输机制和文件上传、下载--将为您一一解答。本节结构为1.MTOM基础概念2.WSE3.0工具配置MTOM3.代码实现与分析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配置工具设置服务端消息传输策略。如图:
客户端设置为on,要求客户端使用MTOM机制进行数据传输。服务端设置为Optional,表示可选这的。此种情况即服务端会根据数据的大小决定是否启用MTOM机制进行数据传递.如果设置为Always,服务端会一直使用MTOM机制进行消息的传递。一般不推荐使用这个方式。OFF即一直不使用MTOM机制进行消息传递。64为最大附加二进制文件的个数。最后表示需要首先使用SOAP消息封装。
对应的配置文件为:
<messaging>
<mtom serverMode="optional" clientMode="On" />
</messaging>
2.2客户端的设置与服务端类似:
客户端配置文件的代码如下:
<messaging>
<mtom clientMode="On" serverMode="optional" />
</messaging>
3.【代码实现与分析】
进行完毕配置以后我们来具体进入代码的开发阶段。这里给出了使用MTOM上传照片的例子,一个使用了证书加密图片上传。先给出服务端的实现,包括两个服务类:WSE3MTOMService和WSE3MTOMSecureService。方法都是二进制字节数据流的传递。
3.1WSE3MTOMService直接实现基于MTOM机制的图片上传和下载方法,具体实现如下:
//WSE 3.0 Samples中的MTOM示例演示了:不加密上传、下载文件、
[WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WSE3MTOMService : System.Web.Services.WebService
{
public WSE3MTOMService()
{
}
//此方法返回不加密的字节数组,下载文件
[WebMethod]
public byte[] DownLoadFile(string fileName)
{
byte[] file = new byte[1024];
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data/" + fileName;
file = File.ReadAllBytes(filePath);
return file;
}
//上传文件,传回2进制数据
[WebMethod]
public void UpLoadFile(byte[] file)
{
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data/" + "FrankXuLei.gif";
if (File.Exists(filePath))
File.Delete(filePath);
File.WriteAllBytes(filePath, file);
}
}
3.2WSE3MTOMSecureService定义了一个文件下载的方法。具体如下:
//WSE 3.0 Samples中的MTOM示例演示了:加密上传、下载文件、
[WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//Returns binary data secured via the ServerPolicy in the wse3policyCache.config policy file
[Policy("ServerPolicy")]
public class WSE3MTOMSecureService : System.Web.Services.WebService
{
public WSE3MTOMSecureService()
{
}
//T通过服务端 X509 证书加密
// MTOM可以使用WS-Security安全协议.
[WebMethod]
public byte[] DownLoadFileWithSecurity(string fileName)
{
byte[] file = null;
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data/" + fileName;
file = File.ReadAllBytes(filePath);//从文件里读取字节流
return file;
}
}
3.3客户端建立控制台应用程序,添加对Web服务的引用。实例化连个代理服务类,进行文件的上传和下载。具体代码如下:
//直接进行数据传输,不需要加密
public void DownLoadFile(String fileName)
{
//实例化服务代理类
WSE3MTOMServiceWse serviceproxy = new WSE3MTOMServiceWse();
//or alternatively set the RequireMtom property on the proxy
//serviceproxy.RequireMtom = true;
//获取文件二进制字节流
byte[] loadFile = serviceproxy.DownLoadFile(fileName);
//打印数据信息
Console.WriteLine("File Name: {0}", fileName);
Console.WriteLine("File has been downloaded without security sucessfully from Server: {0}", loadFile.Length);
//保存文件
String filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;
Console.WriteLine("");
if (File.Exists(filePath))
File.Delete(filePath);
File.WriteAllBytes(filePath, loadFile);
}
//安全方式下载文件
public void DownLoadFileSecure(String fileName)
{
WSE3MTOMSecureServiceWse serviceproxy = new WSE3MTOMSecureServiceWse();
//Set anonymousForCertificateSecurity policy assertion when calling
//this secure service
serviceproxy.SetPolicy("ClientPolicy");
byte[] loadFile = serviceproxy.DownLoadFileWithSecurity(fileName);
//打印数据信息
Console.WriteLine("File Name: {0}", fileName);
Console.WriteLine("File has been downloaded with security sucessfully from Server: {0}", loadFile.Length);
//保存文件
String filePath = AppDomain.CurrentDomain.BaseDirectory + "Secure_"+ fileName;
Console.WriteLine("");
if (File.Exists(filePath))
File.Delete(filePath);
File.WriteAllBytes(filePath, loadFile);
}
//测试非加密安全上传文件
public void UpLoadFile(String fileName)
{
String filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;
//实例化服务代理
WSE3MTOMServiceWse serviceproxy = new WSE3MTOMServiceWse();
//读取文件数据
byte[] upFile = File.ReadAllBytes(filePath);
//调用方法传输数据
serviceproxy.UpLoadFile(upFile);
//输出上传文件信息
Console.WriteLine("File Name: {0}", fileName);
Console.WriteLine("File has been uploaded sucessfully from Client: {0}", upFile.Length);
}
运行结果如图:
首先是上传一个文件到服务器端,然后进行下载操作。均显示成功。可以在程序的运行目录下找到下载的新文件。
4.【总结】
通过以上的介绍和学习,我们知道了一下结论:
1.MTOM机制会效率提升1/3.原因:正常文本 XML 使用 Base64 对二进制数据进行编码,这要求每三个字节对应四个字符,从而使得数据的大小增加三分之一。MTOM 能够以原始字节形式传输二进制数据,这会缩短编码/解码时间并生成较小的消息。
2.使用的场合:MTOM适合大量的数据交换,通常是大量数据情况下才有优势, 如上传文档和图片,目的在于优化对较大的二进制负载的传输。
3.缺陷:对于较小的二进制负载来说,使用 MTOM 发送 SOAP 消息会产生显著的开销。
另外提供本文的代码下载。以供大家学习参考,代码下载连接/Files/frank_xl/WSE3MTOM_FrankXuLei.rar。如有意见也欢迎交流~
Web服务驻留在IIS外,可以由系统服务、控制台程序等托管的方式比较简单,大家可以参考微软的例子,这个WCF里也有类似的寄宿宿主的概念。其实有许多相似之处。
最后在准备《WSE3.0构建Web服务安全》系列文章的过程中,我也收获不少,也希望本系列文能给您的学习带来一些帮助。包括我之前的《WCF分布式开发必备知识》系列都是学习WCF分布式重要知识点的总结。并且全部给出了详细的代码实现和注释。方便大家的学习和实际项目的应用。下面我们将正式进入WCF分布式开发的学习阶段,我会继续给出系统的介绍和详细的实现代码。希望有兴趣的朋友继续关注~谢谢
2.非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
参考资料:
1.BASE64编码基于十进制的实现方法
2.MTOM编码 MSDN
【老徐的博客】
【作者】:Frank Xu Lei
【地址】:http://www.cnblogs.com/frank_xl/archive/2009/03/10/1408173.html