流示例演示了流传输模式通信的使用。 该服务公开了多个用于发送和接收流的操作。 此示例是自承载的。 客户端和服务都是控制台程序。
注释
本示例的设置过程和生成说明位于本主题末尾。
Windows Communication Foundation(WCF)可以在两种传输模式(缓冲模式或流式传输模式)中进行通信。 在默认缓冲传输模式下,必须先完全传递消息,然后接收方才能读取消息。 在流传输模式下,接收方可以在消息完全传递之前开始处理消息。 当传递的信息较长且可串行处理时,流式处理模式非常有用。 当消息太大而无法完全缓冲时,流式处理模式也很有用。
流媒体和服务合同
在设计服务合同时,需要考虑流媒体技术。 如果作接收或返回大量数据,则应考虑流式传输此数据,以避免由于缓冲输入或输出消息而导致内存使用率高。 若要流式传输数据,保存该数据的参数必须是消息中唯一的参数。 例如,如果要对输入消息进行流处理,则该操作必须正好具有一个输入参数。 同样,如果要流式传输输出消息,操作必须正好具有一个输出参数或返回值。 在任一情况下,参数或返回值类型都必须为Stream
或 Message
IXmlSerializable
。 下面是该流处理示例中使用的服务协定。
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IStreamingSample
{
[OperationContract]
Stream GetStream(string data);
[OperationContract]
bool UploadStream(Stream stream);
[OperationContract]
Stream EchoStream(Stream stream);
[OperationContract]
Stream GetReversedStream();
}
GetStream
操作接收一些输入数据作为经过缓冲的字符串,并返回经过流处理的 Stream
。 相反,UploadStream
接收 Stream
(流式处理),并返回 bool
(缓冲)。
EchoStream
接收并返回 Stream
,是一个输入和输出消息都通过流式传输的操作示例。 最后,GetReversedStream
不接受任何输入并返回一个 Stream
(流式)。
启用流传输
按照上面的说明定义操作协定将在编程模型级别提供流处理。 如果停止该位置,传输仍会缓冲整个消息内容。 若要启用传输流式传输,请在传输的绑定元素上选择传输模式。 该绑定元素具有一个 TransferMode
属性,该属性可以设置为 Buffered
、Streamed
、StreamedRequest
或 StreamedResponse
。 将传输模式设置为 Streamed
将在两个方向上启用流通信。 将传输模式设置为 StreamedRequest
或 StreamedResponse
可分别仅在请求或响应中启用流式传输通信。
basicHttpBinding
和TransferMode
以及NetTcpBinding
一样,公开了绑定上的NetNamedPipeBinding
属性。 对于其他传输,必须创建一个自定义绑定以设置传输模式。
示例中的以下配置代码展示了如何将TransferMode
属性设置为basicHttpBinding
上的流式传输和自定义 HTTP 绑定。
<!-- An example basicHttpBinding using streaming. -->
<basicHttpBinding>
<binding name="HttpStreaming" maxReceivedMessageSize="67108864"
transferMode="Streamed"/>
</basicHttpBinding>
<!-- An example customBinding using HTTP and streaming.-->
<customBinding>
<binding name="Soap12">
<textMessageEncoding messageVersion="Soap12WSAddressing10" />
<httpTransport transferMode="Streamed"
maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
除了将 transferMode
设置为 Streamed
之外,以前的配置代码将 maxReceivedMessageSize
设置为 64MB。 作为防御机制, maxReceivedMessageSize
将上限置于接收时允许的最大消息大小。 默认值 maxReceivedMessageSize
为 64 KB,这通常对于流式处理方案来说太低。
处理经过流处理的数据
各个操作GetStream
、UploadStream
和EchoStream
都涉及将数据直接从文件发送或将接收到的数据直接保存到文件中。 但在某些情况下,需要发送或接收大量数据,并在发送或接收数据区块时对数据块执行一些处理。 解决此类方案的一种方法是编写一个自定义流(派生自 Stream的类),该流在读取或写入时处理数据。
GetReversedStream
操作和 ReverseStream
类是一个例子。
GetReversedStream
创建并且返回 ReverseStream
的新实例。 当系统从该 ReverseStream
对象读取时,会发生实际处理。 该 ReverseStream.Read
实现从基础文件读取字节块,反转这些字节,然后返回反向字节。 这不会扭转整个文件内容;它一次反转一个字节块。 这是一个示例,演示如何在从流读取或写入内容时执行流处理。
class ReverseStream : Stream
{
FileStream inStream;
internal ReverseStream(string filePath)
{
//Opens the file and places a StreamReader around it.
inStream = File.OpenRead(filePath);
}
// Other methods removed for brevity.
public override int Read(byte[] buffer, int offset, int count)
{
int countRead=inStream.Read(buffer, offset,count);
ReverseBuffer(buffer, offset, countRead);
return countRead;
}
public override void Close()
{
inStream.Close();
base.Close();
}
protected override void Dispose(bool disposing)
{
inStream.Dispose();
base.Dispose(disposing);
}
void ReverseBuffer(byte[] buffer, int offset, int count)
{
int i, j;
for (i = offset, j = offset + count - 1; i < j; i++, j--)
{
byte currenti = buffer[i];
buffer[i] = buffer[j];
buffer[j] = currenti;
}
}
}
运行示例
若要运行示例,请先按照本文档末尾的说明生成服务和客户端。 然后,在两个不同的控制台窗口中启动服务和客户端。 客户端启动时,它会等待你在服务准备就绪时按 Enter。 然后,客户端会调用这些方法 GetStream()
, UploadStream()
GetReversedStream()
然后首先通过 HTTP,然后通过 TCP。 下面是服务的示例输出,后跟来自客户端的示例输出:
服务输出:
The streaming service is ready.
Press <ENTER> to terminate service.
Saving to file D:\...\uploadedfile
......................
File D:\...\uploadedfile saved
Saving to file D:\...\uploadedfile
...............
File D:\...\uploadedfile saved
客户端输出:
Press <ENTER> when service is ready
------ Using HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream
File D:\...\clientfile saved
------ Using Custom HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Press <ENTER> to terminate client.
设置、生成和运行示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。
注释
如果使用 Svcutil.exe 重新生成此示例的配置,请确保修改客户端配置中的终结点名称以匹配客户端代码。