使用 WCF 和 MTOM 进行流式传输 [英] Streaming with WCF and MTOM

查看:33
本文介绍了使用 WCF 和 MTOM 进行流式传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 WCF 绑定和流式传输模式,用于向/从服务上传和下载二进制内容.我已经设法让它工作.我将包括配置、合同等以供参考.

我做了一些测试来对不同的绑定和编码进行基准测试.上传结果似乎没问题.NetTcp 是最快的,其次是 BasicHttp-MTOM,然后是 BasicHttp-Text.令我惊讶的是,在下载大文件时,MTOM 的速度非常慢,这与使用 BasicHttp 的文本编码和使用 NetTcp 的二进制编码相比非常慢.

我错过了什么吗?为什么 BasicHttp-MTOM 在上传时的工作速度比其他绑定慢?除此之外,我还为下载实现了双缓冲.除了使用 MTOM 编码的 BasicHttp 之外,这也适用于所有绑定.为什么双缓冲在使用 MTOM 时没有帮助?

感谢阅读,感谢您对此的建议和想法.

测试结果:

上传 150 MB 的二进制数据到服务.客户端从 150 MB 文件创建文件流并传递给服务器.服务器将流读入内存流.还没有双缓冲区.结果似乎很快,因为没有将数据写入文件系统.并且绑定按预期执行.

从服务下载 100 MB 的二进制数据.服务创建一个内存流并传递给客户端.客户端写入文件系统.这是单缓冲区和双缓冲区的结果.如你看到的MTOM 似乎非常慢,而且对双缓冲也没有响应.

服务器配置(为简单起见省略了一些部分):

<预><代码><配置><system.web><httpRuntime maxRequestLength="2147483647"/></system.web><system.serviceModel><绑定><netTcpBinding><绑定名称="StreamedNetTcpBinding"transferMode="流媒体"maxReceivedMessageSize="1099511627776"></binding></netTcpBinding><基本HttpBinding><binding name="StreamedBasicHttpBindingWithMtom"messageEncoding="Mtom" transferMode="Streamed"maxReceivedMessageSize="1099511627776"></binding><绑定名称="StreamedBasicHttpBinding"transferMode="流媒体"maxReceivedMessageSize="1099511627776"></binding></basicHttpBinding></绑定></system.serviceModel></配置>

客户端配置(为简单起见省略了一些部分):

<预><代码><配置><system.serviceModel><绑定><基本HttpBinding><绑定名称="StreamedBasicHttpBindingWithMtom"maxReceivedMessageSize="1099511627776"messageEncoding="Mtom" transferMode="Streamed"></binding><绑定名称="StreamedBasicHttpBinding"maxReceivedMessageSize="1099511627776"transferMode="流媒体"></binding></basicHttpBinding><netTcpBinding><binding name="StreamedNetTcpBinding" transferMode="Streamed"maxReceivedMessageSize="1099511627776"></binding></netTcpBinding></绑定></system.serviceModel></配置>

服务合同:

[ServiceContract]公共接口 IFileService{【经营合同】void UploadFile(DocumentData 文档);【经营合同】文档数据下载文件();}

消息合同:

[MessageContract]公共类 DocumentData{[MessageHeader(MustUnderstand = true)]公共字符串文档名称 { 获取;放;}[MessageHeader(MustUnderstand = true)]公共 int FileLength { 获取;放;}[MessageBodyMember(Order = 1)]公共流数据{获取;放;}}

<小时>结果证明这是我在工作中的开发环境设置的问题.当我在家里进行相同的测试时,结果符合预期.

解决方案

我将添加用于实现流媒体的链接,并接受它作为答案.

使用 WCF 上传/下载文件时的进度指示作者:Dimitris Papadimitriou
在从/向流读取/写入时实现双缓冲.(参见 Thomas Levesque 的回答)
另一种双缓冲实现,它做同样的事情.(参见 Nicholas Carey 的回答)
使用SqlFileStream从WCF服务返回流

工作示例链接

I am using WCF bindings with streamed transfer mode, for both uploading and downloading binary content to/from a service. I've managed to get it working. I'll include the configuration, contracts, etc for reference.

I've made some tests to benchmark different bindings and encodings. Uploading results seems ok. NetTcp being the fastest, followed by BasicHttp-MTOM and then BasicHttp-Text. What suprises me is that, when downloading large files, MTOM is very slow as opposed to Text encoding with BasicHttp and Binary encoding with NetTcp.

Am I missing something? Why BasicHttp-MTOM works way slower than other bindings when uploading? Beside that I've implemented double buffering for downloads. This also works well with all bindings except BasicHttp with MTOM encoding. Why double buffering doesn't help when using MTOM?

Thanks for reading, your advice and ideas about this.

Test Results:

Uploading 150 MB binary data to service. Client creates a file stream from a 150 MB file and passes to server. Server reads the stream into a memory stream. No double buffer yet. Results seems fast as there is no writing of data to file system. And bindings perform as expected.

Downloading 100 MB binary data from service. Service creates a memory stream and passes to client. Client writes to file system. Here is the results with both single and double buffer. As you can see MTOM seems extremely slow and doesn't respond to double buffering as well.

Server configuration (left out some parts for simplicity):

<configuration>
  <system.web>
    <httpRuntime maxRequestLength="2147483647"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="StreamedNetTcpBinding"
                 transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
      </netTcpBinding>
      <basicHttpBinding>
        <binding name="StreamedBasicHttpBindingWithMtom"
                 messageEncoding="Mtom" transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
        <binding name="StreamedBasicHttpBinding"
                 transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Client configuration (left out some parts for simplicity):

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="StreamedBasicHttpBindingWithMtom" 
                 maxReceivedMessageSize="1099511627776"
                 messageEncoding="Mtom" transferMode="Streamed">
        </binding>
        <binding name="StreamedBasicHttpBinding"
                 maxReceivedMessageSize="1099511627776"
                 transferMode="Streamed">
        </binding>
      </basicHttpBinding>
      <netTcpBinding>
        <binding name="StreamedNetTcpBinding" transferMode="Streamed"
          maxReceivedMessageSize="1099511627776">
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Service Contract:

[ServiceContract]
public interface IFileService
{
    [OperationContract]
    void UploadFile(DocumentData document);

    [OperationContract]
    DocumentData DownloadFile();
}

Message Contract:

[MessageContract]
public class DocumentData
{
    [MessageHeader(MustUnderstand = true)]
    public string DocumentName { get; set; }

    [MessageHeader(MustUnderstand = true)]
    public int FileLength { get; set; }

    [MessageBodyMember(Order = 1)]
    public Stream Data { get; set; }
}


Edit: This turned out to be an issue with my development environment setup at work. When I ran the same tests at home, the results was as expected.

解决方案

I'll add links that I used to implement streaming and accept this as an answer.

Progress Indication while Uploading/Downloading Files using WCF By Dimitris Papadimitriou
Implementation of double buffering while reading/writing from/to a stream. (See Thomas Levesque's answer)
Another implementation for double buffering, which does the same thing. (See Nicholas Carey's answer)
Return Stream from WCF service, using SqlFileStream

Working Sample Link

这篇关于使用 WCF 和 MTOM 进行流式传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆