c# - 如何在不缓冲的情况下流式传输来自 WCF 的响应?

标签 c# .net wcf rest stream

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

我有几个触发长时间运行方法的 GET 方法,我想将日志响应流式传输到浏览器(或应用程序),以便用户知道发生了什么。使用 HttpContext.Current.Response.OutputStream.Write 可以轻松完成此操作。不幸的是,即使我包含 aspNetCompatibilityEnabled 配置(不幸的是,IIS 不是一个选项),HttpContext.Current 在自托管 WCF 服务中始终为 null。

我试过AnonymousPipeServerStream: WCF and streaming requests and responses

连同第一个设置:

OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.ContentType = "text/plain";

为了使响应进入浏览器,它不会将流下载到文件中进行保存。

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

让 chrome 输出的修复显然是在发送分块响应之前向内容写入一些垃圾:Chunked transfer encoding - browser behavior ,但是,我认为这对于 WCF 是不可能的。

所以,我正在寻找可能的解决方案:

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

我想,另一种选择是放弃 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,您的文件流将在读取到文件末尾之前开始返回字节。通过 WCF 流式传输的工作方式相同(事实上,根据我的经验,它实现了 FileStream),这就是它适用于大量数据的原因。它读取...它发送;它读取...它发送。所以我不确定您如何将一些信息注入(inject)该流以输出到您的屏幕。

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

关于c# - 如何在不缓冲的情况下流式传输来自 WCF 的响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23604828/

相关文章:

c# - 检测非 DPI 感知应用程序是否已缩放/虚拟化

json - 不要在 JSON 响应中发送 null

asp.net-mvc - 今天,在.NET中实现RESTful架构的最佳方法是什么?

c# - 如何从后面的 c# 代码调用 javascript 函数

c# - 如何在xml注释<code>标签中指定语言

c# - 是否可以在我的应用程序中添加数据源连接向导?

c# - 在 WCF 和 .NET 4.0 中使用 TLS 1.1 或 1.2?

c# - 检查类型是否属于没有硬编码字符串的 namespace

c# - UWP 中的 GridView

c# - 为什么属性会这样?