【问题标题】:Why are chunked responses not entirely served?为什么没有完全提供分块响应?
【发布时间】:2014-05-22 07:58:50
【问题描述】:

您好 Play/Scala 开发人员。我不知道这样的问题是属于这里还是属于其他某种面向网络的 Q/A,但这里是这样的:

我有一个 Play 应用,它通过使用多个请求调用另一个服务来提供搜索结果。对不同请求的响应以块的形式发送。基本上所有请求都会被触发,一旦请求完成,结果就会使用 Comet 发回:我使用 Play's doc 描述的 iframe 方法。

但是,我注意到在某些情况下,iframe 调用在所有数据发送回最终用户之前完成。我调试了一下,发现请求最终全部完成,我的浏览器显示 net::ERR_INCOMPLETE_CHUNKED_ENCODING。我还注意到传输到 UI 的数据量因浏览器而异。

我的结果如下所示:

Ok.chunked(
      (stringEnumerator1 &> Comet(callback = "script1")) >- 
      (stringEnumerator2 &> Comet(callback = "script2")) >- 
      (stringEnumerator3 &> Comet(callback = "script3")) 
).as(HTML)

就我在Play's doc 中阅读的内容而言,这应该可以解决问题,但它没有,我不知道如何解决这个问题。有没有人对此有一点想法或提示?

编辑

这是枚举器的创建方式。一旦发出对远程服务器的调用,我会得到一个 Future 和一个 Option 的一个 case class 我期待来自一个特定的调用。这个未来被传递给在给定case class 上调用方法(toHTML)的方法,该方法创建一个HTML Elem,一旦在客户端调用回调,该方法基本上附加到给定divPart 是我的案例类继承的抽象类,然后实现toHTML 方法。

这里是将给定部分转换为HTML字符串的方法:

def getEnumerator[X <: Part](part: Future[Option[X]]): Enumerator[String] = 
    Enumerator.flatten(part.map(Enumerator(_))).map(xopt => xopt.map(x => x.toHTML.toString).getOrElse(PartNotFound().toHTML.toString))

编辑 2

我发现问题出在哪里,问题是在我的HTML 一代中,有两个整数之和,其中一个整数在某个时刻null,这使得HTML 一代失败, Play 然后断开了连接,让我感到烦恼的是,当那个总和发生时,Play 没有抛出异常。

【问题讨论】:

  • AFAIK 枚举器应以EOF 结尾。你能检查一下你收到了吗?
  • 我尝试将.addThen(Enumerator.eof) 添加到我现有的枚举器中,但没有解决问题。
  • 我猜你的stringEnumerators 之一没有完成。尝试用Enumerator("dummy data here") 替换它们,看看你会得到什么行为。另外,您能否发布其中一个Enumerators 的代码?
  • @wingedsubmariner,请参阅我的编辑了解更多信息。

标签: scala iframe playframework playframework-2.2 future


【解决方案1】:

出现“不完整的分块编码”错误是因为用于构建您的 EnumeratorFuture 完成失败。

HTTP 无法传达在发送响应的过程中发生了错误,即使是分块响应也是如此。当你给 Play 的 Ok.chunked 一个失败的 Enumerator 时,它有两种选择如何响应:

  1. 交付最终的空块以完成请求。这是不诚实的,前端的任何东西都无法判断发生了错误。
  2. 断开连接。

Play 选择选项 2,这是导致“不完整的分块编码”错误的原因。

解决此问题的方法是尽可能确保您的Enumerator 不会失败。这是处理失败的FuturegetEnumerator 方法的替代品:

def getEnumerator[X <: Part](part: Future[Option[X]]): Enumerator[String] =
  Enumerator.flatten {
    part recover {
      case _ => Some(ErrorGettingPart)
    } map { x =>
      Enumerator(x.getOrElse(PartNotFound).toHTML.toString)
    }
  }

【讨论】:

  • 实际上,我发现了问题,问题是在我的 HTML 生成中,有两个整数之和,其中一个整数在某些时候为空,这导致 HTML 生成失败,并且正如你所说,Play 断开了连接,让我感到烦恼的是,当那个总和发生时,Play 没有抛出异常。
猜你喜欢
  • 2023-03-06
  • 2011-06-18
  • 2021-03-25
  • 1970-01-01
  • 2015-12-20
  • 2017-08-08
  • 2014-08-06
  • 1970-01-01
  • 2016-11-18
相关资源
最近更新 更多