WCF和流请求和响应 [英] WCF and streaming requests and responses

查看:115
本文介绍了WCF和流请求和响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

它正确,在WCF,我不能有一个服务的应用于接收到客户端的流?

Is it correct that in WCF, I cannot have a service write to a stream that is received by the client?

流被用于请求,响应,或两者支持WCF。 我愿意支持这样一个场景,数据生成器(无论是在案件的流请求,或在流式响应的服务器的客户端)可以在数据流写入。是否支持?

Streaming is supported in WCF for requests, responses, or both. I would like to support a scenario where the data generator (either the client in case of streamed request, or the server in case of streamed response) can Write on the stream. Is this supported?

这个比喻是从ASP.NET请求Response.OutputStream。在ASPNET,任何页可以在输出流上调用写入,并且接收由客户端的内容。我可以做一个WCF服务类似的东西 - 在接收到客户端的流调用写?

The analogy is the Response.OutputStream from an ASP.NET request. In ASPNET, any page can invoke Write on the output stream, and the content is received by the client. Can I do something similar in a WCF service - invoke Write on a stream that is received by the client?

让我有一个WCF说明解释。流媒体在WCF最简单的例子是服务的FileStream返回给客户端。这是一个流式的反应。服务器code来实现这一点,是这样的:

Let me explain with a WCF illustration. The simplest example of Streaming in WCF is the service returning a FileStream to a client. This is a streamed response. The server code to implement this, is like this:

[ServiceContract]
public interface IStreamService
{
    [OperationContract]
    Stream GetData(string fileName);
}
public class StreamService : IStreamService
{
    public Stream GetData(string filename)
    {
        return new FileStream(filename, FileMode.Open)
    }
}

和客户端code是这样的:

And the client code is like this:

StreamDemo.StreamServiceClient client = 
    new WcfStreamDemoClient.StreamDemo.StreamServiceClient();
Stream str = client.GetData(@"c:\path\on\server\myfile.dat");
do {
  b = str.ReadByte(); //read next byte from stream
  ...
} while (b != -1);

(比如取自 http://blog.joachim.at/?p=33

清除,对不对?服务器返回流给客户端,客户端调用就可以读取。

Clear, right? The server returns the Stream to the client, and the client invokes Read on it.

是否有可能为客户端提供一个流,服务器调用写在上面?
换句话说,而不是拉模型 - 其中客户端提取数据从服务器 - 它是一个推模式,其中客户端提供了下沉流和服务器写入它。服务器端code可能类似于此:

Is it possible for the client to provide a Stream, and the server to invoke Write on it?
In other words, rather than a pull model - where the client pulls data from the server - it is a push model, where the client provides the "sink" stream and the server writes into it. The server-side code might look similar to this:

[ServiceContract]
public interface IStreamWriterService
{
    [OperationContract]
    void SendData(Stream clientProvidedWritableStream);
}
public class DataService : IStreamWriterService
{
    public void GetData(Stream s)
    {
        do {
          byte[] chunk = GetNextChunk();
          s.Write(chunk,0, chunk.Length);
        } while (chunk.Length > 0); 
    }
}

在WCF这是可能的,如果是这样,怎么样?什么是需要绑定,接口等的配置设置?什么是术语?

Is this possible in WCF, and if so, how? What are the config settings required for the binding, interface, etc? What is the terminology?

也许这只是工作? (我还没有尝试过)

Maybe it will just work? (I haven't tried it)

感谢。

推荐答案

我的非常的肯定,有WCF绑定的任何组合,将让你的字面上的写到客户端的数据流。它似乎合乎逻辑的,应该有,因为表面某处之下还有的肯定会是一个的NetworkStream ,但一旦你开始添加加密和所有有趣的东西,WCF会必须知道如何来包装这个流把它变成真正的消息,我不认为它。

I'm fairly certain that there's no combination of WCF bindings that will allow you to literally write to the client's stream. It does seem logical that there should be, given that somewhere beneath the surface there's definitely going to be a NetworkStream, but once you start adding encryption and all that fun stuff, WCF would have to know how to wrap this stream to turn it into the "real" message, which I don't think it does.

不过,我-需要对回报一个流,但是分量-X-希望对写入到一个场景是一个常见的​​一种,而我有我使用一个包罗万象的解决方案对于这种情况,这是创建一个双向流,并生成一个工作线程写入。在简单安全的方式做到这一点(我的意思是,这涉及到写作至少code和方式,因此最有可能是越野车)是使用匿名管道。

However, the I-need-to-return-a-stream-but-component-X-wants-to-write-to-one scenario is a common one, and I have a catch-all solution that I use for this scenario, which is to create a two-way stream and spawn a worker thread to write to it. The easiest and safest way to do this (by which I mean, the way that involves writing the least code and therefore least likely to be buggy) is to use anonymous pipes.

下面是一个返回的 AnonymousPipeClientStream 可以在WCF消息,MVC结果被使用,等等 - 任何你想要反转的方向:

Here's an example of a method that returns an AnonymousPipeClientStream that can be used in WCF messages, MVC results, and so on - anywhere you want to invert the direction:

static Stream GetPipedStream(Action<Stream> writeAction)
{
    AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream();
    ThreadPool.QueueUserWorkItem(s =>
    {
        using (pipeServer)
        {
            writeAction(pipeServer);
            pipeServer.WaitForPipeDrain();
        }
    });
    return new AnonymousPipeClientStream(PipeDirection.In, pipeServer.ClientSafePipeHandle);
}

这方面的一个例子用法是:

An example usage of this would be:

static Stream GetTestStream()
{
    string data = "The quick brown fox jumps over the lazy dog.";
    return GetPipedStream(s =>
    {
        StreamWriter writer = new StreamWriter(s);
        writer.AutoFlush = true;
        for (int i = 0; i < 50; i++)
        {
            Thread.Sleep(50);
            writer.WriteLine(data);
        }
    });
}

就在这个方法的注意事项:

Just two caveats about this approach:

  1. 这将失败,如果的WriteAction 没有任何处分流(这就是为什么测试方法实际上并不处置的StreamWriter - 因为这将处置底层流);

  1. It will fail if the writeAction does anything to dispose the stream (that's why the test method doesn't actually dispose the StreamWriter - because that would dispose the underlying stream);

这可能会失败,如果的WriteAction 实际上并没有写入任何数据,因为 WaitForPipeDrain 返回立即创建一个竞争条件。 (如果这是一个问题,你可以codea的多一点防守,以避免这种情况,但复杂的事情很多了难得的边缘情况。)

It might fail if the writeAction doesn't actually write any data, because WaitForPipeDrain will return immediately and create a race condition. (If this is a concern, you can code a little more defensively to avoid this, but it complicates things a lot for a rare edge case.)

希望这有助于您的具体情况。

Hopefully that helps in your specific case.

这篇关于WCF和流请求和响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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