Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在没有缓冲的情况下从WCF传输响应?_C#_.net_Wcf_Rest_Stream - Fatal编程技术网

C# 如何在没有缓冲的情况下从WCF传输响应?

C# 如何在没有缓冲的情况下从WCF传输响应?,c#,.net,wcf,rest,stream,C#,.net,Wcf,Rest,Stream,我有一个restful(webHttpBinding)自托管WCF服务。大多数方法都将对象的xml或json版本返回给客户端 我有几个GET方法可以触发长时间运行的方法,我希望将日志响应流式传输到浏览器(或应用程序),以便用户知道发生了什么。使用HttpContext.Current.Response.OutputStream.Write可以很容易地实现这一点。不幸的是,HttpContext.Current在自托管WCF服务中始终为空,即使我包括aspNetCompatibilityEnabl

我有一个restful(webHttpBinding)自托管WCF服务。大多数方法都将对象的xml或json版本返回给客户端

我有几个GET方法可以触发长时间运行的方法,我希望将日志响应流式传输到浏览器(或应用程序),以便用户知道发生了什么。使用
HttpContext.Current.Response.OutputStream.Write
可以很容易地实现这一点。不幸的是,
HttpContext.Current
在自托管WCF服务中始终为空,即使我包括
aspNetCompatibilityEnabled
config(不幸的是,IIS不是选项)

我尝试了
匿名PipeServerStream

随着第一次设置:

OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.ContentType = "text/plain";
因此,响应进入浏览器,而不是将流下载到要保存的文件中

在Chrome中,它根本不起作用——它会一直缓冲到最后。在IE或wget中,它似乎一次缓冲大约4k(或更多)。这对日志记录没有好处,因为除非我吐出大量不必要的日志消息来强制输出,否则用户并不真正知道发生了什么。我只能假设这是因为响应实际上是一个分块响应,分块是4k(而不仅仅是写入outputstream)

让chrome输出的修复方法显然是在发送分块响应之前向内容写入一些垃圾:,然而,我认为这在WCF中是不可能的

因此,我正在寻找可能的解决方案:

  • 在自托管服务(无IIS)中写入WCF中输出流的方法。 或
  • 一种在流响应中控制块大小的方法(一种先写入一些内容以便Chrome呈现块的方法)

我想,另一个选择是放弃WCF,转而选择更为REST友好的方式(我开始认为WCF不是正确的选择)。然而,现在已经用WCF写了这么多东西,这似乎是一项乏味的任务。除非我可以切换到某个简单的迁移(例如,如果我可以重用相同的服务类,可能只是使用不同的属性)。可能是南希吧?

我做了一些类似于你在这里询问的事情——也是自我主持的。我编写了一个WCF(BasicHttpBinding)服务,它向使用我的服务进行数据同步的客户端设备提供数据流和缓冲。正如你可能已经了解到的,流媒体很难,我认为没有任何方法可以“写入流”

从基本意义上讲,WCF服务上的流与File.IO的工作方式相同,如下面的代码所示

 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
 BinaryReader br = new BinaryReader(fs);
如果所讨论的文件为1 GB,则filestream将在读取到文件末尾之前开始返回字节。WCF上的流也以同样的方式工作(事实上,根据我的经验,它实现了FileStream),这就是为什么它适用于海量数据的原因。上面写着。。。它发送;上面写着。。。它发送了一个消息。因此,我不确定如何将一些信息注入到该流中,以便输出到屏幕


话虽如此,我们的同步UI显示下降的字节数,加上完成的百分比,以防止用户关闭机器或取消。我们通过让一个单独的线程每10秒读取一次下载文件的大小,并计算整个文件的百分比(完整的大小作为响应中的一个参数发送回来),然后将结果写到UI结果窗口。因此,在我们的例子中,解决方案实际上非常简单

我这样做文件流:

将返回需要流式传输到端点的数据的方法分组,然后在该端点上添加流式传输模式

以下是我使用的配置(用于basicHttpBinding)


并定义绑定配置:

<bindings>
    <basicHttpBinding>
        <binding name="IntersolveWebServicesStreamedBinding" allowCookies="true" transferMode="Streamed" maxReceivedMessageSize="67108864" />
    </basicHttpBinding>
</bindings>

基本上,您必须在绑定配置中设置transferMode


我还没有尝试过webHttpBinding,所以请让我知道它是否适合您。

只要诱使浏览器认为有一个带有
多部分内容类型的HTML响应


我已经用它做了很多事情,包括MJPEG,但你也可以用它来做COMET/WebSocket之类的响应。

所以,在你看来,我想做的是不可能的?我想这取决于你想做什么。您从一个地方移动到另一个地方的是原始数据吗?流媒体通常用于巨大的数据集(即,我们从Amazon流媒体播放音乐和电影),一旦流媒体开始,客户端和主机就会同步发送和接收,直到流程完成。我不知道你想怎样或者为什么要在这种流中注入一些东西。如果你担心你的用户因为看不到进展而做了一些奇怪的事情,那么有一些方法(正如我所描述的)可以解决这个问题。因此,数据量可能从几行(如果进展顺利)到1000行(如果进展不顺利)。这是我过去通过向输出流(使用.NET和其他语言)写入数据而没有问题的做法,但问题似乎是WCF并没有给我我想要的灵活性。我目前也有这样的印象,因为WCF的构建并没有考虑Restful世界(Rest通常不会映射到RPC用例)为了这个目的,最好放弃它,改用像Nancy这样的东西。我已经不得不转而使用JSON.NET进行JSON序列化,因此WCF staack实际上只为我提供了一个轻量级的web服务器和身份验证。您是否考虑过使用WebSocket将日志数据“流”到客户端。您仍然可以使用WCF进行REST调用,但让服务器传输到您也在客户端中侦听的websockets服务器。。或者类似的东西。我已经试过了,但WCF似乎控制了缓冲区中的数据量
<bindings>
    <basicHttpBinding>
        <binding name="IntersolveWebServicesStreamedBinding" allowCookies="true" transferMode="Streamed" maxReceivedMessageSize="67108864" />
    </basicHttpBinding>
</bindings>