转:wcf大文件传输解决之道(1)
首先声明,文章思路源于MSDN中徐长龙老师的课程整理,加上自己的一些心得体会,先总结如下:
在应对与大文件传输的情况下,因为wcf默认采用的是缓存加载对象,也就是说将文件包一次性接受至缓存中,然后生成对象,显然对于大文件的传输,这种方式是不可取的,一般我们采用流传输或者更优秀的本本编码方式,在文本编码这一块我们一般采用w3c提出的MTOM传输机制,MTOM(Message Transmission Optimization Mechanism),是W3C的MTOM的消息传输优化机制,有效地发送的二进制数据和从Web服务方法。将消息传输优化机制 (MTOM) 消息编码与WSHttpBinding 一起使用。MTOM是一种机制,用来以原始字节形式传输包含SOAP消息的较大二进制附件,从而使所传输的消息较小。也就是说它对于文件的编码采取的文件头和文件包得传输方式,文件头定义文件格式,文件包采用SOAP原始的二进制信息,实现信息的优化,但这种方式在文件较小的时候相对于普通的文本编辑方式也是有耗损的,下面通过一个案例比较下:
新建方法,实现文本编码方式和MTOM方式编码的比较
///<summary>
/// 新建函数,用于测试moto方式对数据进行编码所生成的对象长度比较
///</summary>
///<param name="dataSize"></param>
static void CompareMessageSize(int dataSize)
{
byte[] binaryData = new byte[dataSize]; Message message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "消息说明", binaryData);//创建一个soap消息 MessageBuffer buffer = message.CreateBufferedCopy(int.MaxValue);//新建一个消息缓存区域并将消息传入 int size = SizeofTextMessage(buffer.CreateMessage());
Console.WriteLine("text endcoding with a {0} byte playod:{1}", binaryData.Length, size); size = sizeofMotoMessage(buffer.CreateMessage());
Console.WriteLine("MTMO endcoding with a {0} byte playod:{1}", binaryData.Length, size);
Console.WriteLine(); message.Close();//关闭流
}
新建方法,实现MTOM方式编码
private static int sizeofMotoMessage(Message message)
{
//创建一个文本编码器
MessageEncodingBindingElement element = new MtomMessageEncodingBindingElement();
MessageEncoderFactory factory = element.CreateMessageEncoderFactory();
MessageEncoder encoder = factory.Encoder; MemoryStream sream = new MemoryStream(); //创建内存
encoder.WriteMessage(message, sream); //通过文本编辑器将消息写到内存中 int size = (int)sream.Length;
message.Close();
sream.Close();
return size;
}
新建另一个方法,实现默认文本方式编码
private static int SizeofTextMessage(Message message)
{
//创建一个Mtom编码器
MessageEncodingBindingElement element = new TextMessageEncodingBindingElement();
MessageEncoderFactory factory = element.CreateMessageEncoderFactory();
MessageEncoder encoder = factory.Encoder; MemoryStream sream = new MemoryStream(); //创建内存
encoder.WriteMessage(message, sream); //通过文本编辑器将消息写到内存中 int size = (int)sream.Length;
message.Close();
sream.Close();
return size; }
调用方式比较传输:
///比较文本编码方式和Moto方式两者编码的不同,两者都适用于Http协议传输,在1Mb下文本编辑方式为
///最佳选择,Moto适合大文件传输,在跨平台上无疑这是最好的选择
CompareMessageSize();
CompareMessageSize();
CompareMessageSize();
CompareMessageSize();
CompareMessageSize(); Console.ReadLine();
看运行结果:
显然在字节大于2000字节的时候MOTO方式的编码长度小于普通编码方式,而在小于2000字节的时候普通文本编辑要优于MTOM编码方式
所以在我们定义Binding的时候我们要分情况对待。
我们在wcf中应用MTOM的方式是通过定义Binding的方式进行的,看配置代码
<!--定义bangings-->
<bindings>
<!--文本编码方式是Mtom方式,传输协议是wsHttpBinding-->
<wsHttpBinding>
<binding name="wsHttpBing_IUpload" messageEncoding="Mtom" />
</wsHttpBinding> <!--流编码方式transferMode启动流模式,设置流模式类型-->
<basicHttpBinding>
<binding name="myBinding" transferMode="Streamed" />
</basicHttpBinding>
</bindings>
这里面定义了两种Binding编码方式,一个是采取Mtom方式、另一个是采取流媒体;其实两者是有区别的:
1、BasicHttpBinding发送的是明文数据,而WsHttpBinding发送的是加密和更加安全的数据
2、如果你希望有向后兼容的能力,并且支持更多的客户端,你可以选择basicHttpBinding,如果你确定你的客户端使用的 是.NET .0甚至更高的话,你可以选择wsHttpBinding
也就是说 basicHttpBinding扩展性好,而wshttpBinding必须给予..0以上版本 当然流媒体传输的速度相对会优于文本传输,但流开启的条件是有约束的:
有于stream的限制,只能对流模式使用传输级别的安全选项,并且无法打开 可靠会话,因此,流模式仅在下列系统定义的绑定中使用
BasicHttpBinding
NetTcpBinding
NetNamedPipeBinding
并且流模式传输时只能定义一个参数,如果添加多个参数,则自动转换成文本编码方式,用缓存来实现
不同的应用环境分情况对待,我们看上面的配置我们如何应用,客户端定数据契约和方法:
namespace service
{
[ServiceContract(Namespace = "http://localhost/Server")]
public interface IUplod
{
[OperationContract]
int Upload(Stream data);
}
public class UploadService : IUplod
{
public int Upload(Stream data)
{
int size = ;
int bytesRead = ;
byte[] buffer = new byte[]; //新建字节数组 //从流中读取信息存储到字节数组中
do
{
bytesRead = data.Read(buffer, , buffer.Length); //
size += bytesRead; }
while (bytesRead > );
data.Close();
return size;
}
}
}
采用自托管的方式:
namespace service
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(UploadService)))
{
host.Opened += delegate
{
Console.WriteLine("服务已经启动");
};
host.Open();
Console.ReadLine();
}
}
}
}
客户端实现流传输:
byte[] binaryData = new byte[];
//定义1000长度的字节数组
MemoryStream sream = new MemoryStream(binaryData);
//生成内存里流.MemorySteam继承自sream,是stream的实例
ServiceUplod.UplodClient client = new ServiceUplod.UplodClient();
Console.WriteLine(client.Upload(sream));
//调用服务传入1000个字节
sream.Close();//关闭流
运行结果:
呵呵...这种方式只应用于http协议传输,通过MTOM或者流媒体传输实现,流媒体的传输,在使用TCP协议的情况下我们能更大限度的使用流媒体传输,当然既然优越就有它的限制性,下一篇我们分析,基于此种协议进行大文件传输
来自:http://www.cnblogs.com/zhijianliutang/archive/2011/11/28/2265858.html
转:wcf大文件传输解决之道(1)的更多相关文章
- 转:wcf大文件传输解决之道(2)
此篇文章主要是基于http协议应用于大文件传输中的应用,现在我们先解析下wcf中编码器的定义,编码器实现了类的编码,并负责将Message内存中消息转变为网络发送的字节流或者字节缓冲区(对于发送方而言 ...
- WCF大文件传输【转】
http://www.cnblogs.com/happygx/archive/2013/10/29/3393973.html WCF大文件传输 WCF传输文件的时候可以设置每次文件的传输大小,如果是小 ...
- WCF大文件传输服务
由于项目需要,自己写一个基于WCF的大文件传输服务雏形.觉得有一定的参考价值,因此放在网上分享. 目前版本为v1.1特点如下: 1.文件传输端口为18650 2.上传和下载文件 3.支持获取文件传输状 ...
- WCF大文件传输
WCF传输文件的时候可以设置每次文件的传输大小,如果是小文件的时候,可以很方便的将文件传递到服务端,但是如果文件比较大的话,就不可取了 遇到大文件的话可以采取分段传输的方式进行文件传输 思路: 1.客 ...
- WCF 大文件传输配置
<bindings> <webHttpBinding> <!--这个是接收大数据加的,设置WCF服务器端数据接收上限参数,此处单位字节,故2147483647字节==2G ...
- Nginx集群之WCF大文件上传及下载(支持6G传输)
目录 1 大概思路... 1 2 Nginx集群之WCF大文件上传及下载... 1 3 BasicHttpBinding相关配置解析... 2 4 编写 ...
- 大文件传输 分片上传 上传id 分片号 授权给第三方上传
https://www.zhihu.com/question/39593108 作者:ZeroOne链接:https://www.zhihu.com/question/39593108/answer/ ...
- 【转】Windows2008上传大文件的解决方法(iis7解决上传大容量文件)
2008上传大文件的解决方法:http://wenku.it168.com/d_000091739.shtml 2003上传大文件的解决方法:http://tech.v01.cn/windowsxit ...
- 利用Socket进行大文件传输
分类: WINDOWS 最近接触到利用socket进行大文件传输的技术,有些心得,与大家分享.首先看看这个过程是怎么进行的(如下图): 所以,我们需要三个socket在窗体加载的时候初始化: ...
随机推荐
- 【托业】【新托业TOEIC新题型真题】学习笔记9-题库七+八--P4-5
109.intend 意为“打算,意欲”,含有将来的含义,故不用将来时态 110.must do sth 必须做某事 111.recession 经济衰退,不景气 rebound 反弹:反应 recr ...
- 剑指offer-合并两个排列的链接
题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. public ListNode Merge(ListNode list1,ListNode ...
- SQL优化之踩过的坑【一】
正看资料看的过瘾,突然收到报警,说服务器负载太高,好吧,登录服务器看看,我擦嘞,还能不能愉快的玩耍了?下面是当时的负载情况 看见mysql使用cpu已经到了2000,io没有等待.说明应该没有大的临时 ...
- 前端 chrome查看html样式基本操作
Chrome浏览器是世界上HTML5支持最好的浏览器.提供了非常好的开发工具,非常适合我们开发人员使用.审查元素功能的快捷键是F12. 按检查或者F12 鼠标点击找标签 chorme审查元素的使用 - ...
- 晨枫U盘启动盘制作工具V4.0-安装原版XP的方法
[1]进入第一个PE后找到我们事先准备好的xp光盘iso镜像,右键点击加载虚拟磁盘(也可以利用虚拟光驱来加载或者直接用右键里的RAR解压到本地硬盘分区) [2]打开桌面上的windows安装工具,wi ...
- localStorage 不方便存储数组时的替代方法
项目背景是需要将搜索历史存储到localStorage中, 需要存储id和name,每次存储时都需要在记录中多加一条,用数组push显然是比较好的方法,但localStorage不方便存储数据,于是就 ...
- WebStrom2018注册码
2RRJMBXW33-eyJsaWNlbnNlSWQiOiIyUlJKTUJYVzMzIiwibGljZW5zZWVOYW1lIjoi5b285bK4IHNvZnR3YXJlMiIsImFzc2lnb ...
- syslog-ng 学习
摘要:http://luyongxin88.blog.163.com/blog/static/925580720112275183903/ 因为工作的需要,涉及到了syslog-ng.现在看来,在外包 ...
- Windows下解压分卷压缩方法
各种压缩分卷格式 rar分卷格式是*.part1.rar,*.part2.rar 等等. 360分卷压缩出来的文件的名字是*.zip.001.*.zip002 等等. WinZip分卷压缩出来的文件名 ...
- mybatis test条件判断 如何引用 传入的 list参数中的map中的值
<select id="query" resultType="map"> select * from ${tbName} <where> ...