scala - 将 Play 框架中的 WebSockets 从版本 2.4 转换为 2.6

标签 scala websocket playframework-2.4 playframework-2.6 playframework-webservice

我正在尝试将这段使用 Play 版本 2.4 的代码转换为当前版本 (2.6),但我遇到了一些问题,因为我仍然是 Scala 新手。

def wsWeatherIntervals = WebSocket.using[String] {
  request =>
    val url = "http://api.openweathermap.org/data/2.5/weather?q=Amsterdam,nl"
    val outEnumerator = Enumerator.repeatM[String]({
      Thread.sleep(3000)
      ws.url(url).get().map(r => s"${new java.util.Date()}\n ${r.body}")
    })
    (Iteratee.ignore[String], outEnumerator)
}

我关注了this guide ,但现在我陷入了应该在方法中返回的内容。 这是我尝试使用 2.6 版本运行的代码:

  import play.api.mvc._
  import scala.concurrent.Future
  import akka.stream.scaladsl._
  def wsWeatherIntervals = WebSocket.accept[String, Future[String]] { res =>
    val url = "http://api.openweathermap.org/data/2.5/weather?q=Amsterdam,nl"
    val source = Source.repeat({
      Thread.sleep(3000)
      ws.url(url).get().map(r => s"${new java.util.Date()}\n ${r.body}")
    })
    Flow.fromSinkAndSource(Sink.ignore, source)
  }

但是我在运行服务器时收到此错误,该错误指向方法的第一行:

could not find implicit value for parameter transformer: play.api.mvc.WebSocket.MessageFlowTransformer[String,scala.concurrent.Future[String]]

注意:我还尝试调用 WebSocket.apply 而不是 WebSocket.accept 并且我对两者之间的差异进行了一些搜索,但没有找到任何有用的东西。有人可以解释两者之间的区别吗?谢谢。

最佳答案

表面上的错误是 Play 不知道如何将 Future[String] 转换为 Websocket 消息,而您通常会使用隐式转换器。但是,在这种情况下,您无论如何都不想返回 Future[String] 而只是返回一个可以自动编码的普通字符串(在发生时使用提供的 stringMessageFlowTransformer .) 这是应该有效的东西:

def wsWeatherIntervals = WebSocket.accept[String, String] { res =>
  val url = "http://api.openweathermap.org/data/2.5/weather?q=Amsterdam,nl"
  def f = ws.url(url).get().map(r => s"${new java.util.Date()}\n ${r.body}")

  val source = Source.unfoldAsync(f)(last => {
    Thread.sleep(3000)
    f.map(next => Some((last, next)))
  })
  Flow.fromSinkAndSource(Sink.ignore, source)
}

unfoldAsync 源让我们重复运行一个函数,返回流中下一个元素的 future 。 (因为我们希望流永远持续下去,所以我们返回包装为 Some 的值。)

Websocket.apply 方法基本上是 accept 的更复杂版本,它允许您通过返回响应来拒绝 Websocket 连接,但如果您需要为此,最好使用 acceptOrResult,它负责将流程发出的任何内容转换为 Websocket 消息。

关于scala - 将 Play 框架中的 WebSockets 从版本 2.4 转换为 2.6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46266802/

相关文章:

scala - PartialFunction 和 Function1 有什么关系

scala - 为什么 dataset.count() 比 rdd.count() 快?

scala - 如何访问通过guice创建的akka​​系统?

playframework - Play框架处理请求超时

java - 我们可以再次使用相同的 websocket 连接吗?

java - Scala 在编译器镜像中返回 "error while loading package, Missing dependency ' 对象 java.lang.Object'"

scala - 在 Scala 中是否使用上下文绑定(bind)或隐式 ev

scala - 方法和领域有什么区别?

c++ - nopoll 丢失连接发现

javascript - 使用 javascript 监控 twilio 调用