在 Scala 控制器中实现 WebSocketClient

Implementing a WebSocketClient in Scala controller

我有一个 Scala 控制器,我在其中使用 WS api Play 调用外部网络服务!其中returns个框架json。现在使用 WebSocketClient 调用相同的 api,因为每个连接都应该使用 WebSocket 而不是 http。所以控制器中的正常 Action 被转换为 WebSocket 函数,但是我无法从 scala 代码中调用 WebSocket 函数。我已经在网上搜索并浏览了多个地方的解决方案,但我没有在任何地方找到解决方案。如何做到这一点,调用 WebSocket 函数并使用 Scala 代码中的 WebSocketClient 获取其 json 或者我们可以说,从 Scala 代码中使用 WebSocket ?我在 SO 上发现了一个与我的问题类似的问题,但是 none 已经给出了答案!我想知道它在 Play 框架中是否可行?

Consume a WebSocket connection using Scala and Play

编辑:我正在执行以下代码:

val c = new AsyncHttpClient()
val webSocketClient = c.prepareGet("ws://0.0.0.0:9000/testSocket").execute(new WebSocketUpgradeHandler.Builder().addWebSocketListener(new WebSocketTextListener {

  override def onMessage(s: String): Unit = {
  }

  override def onOpen(webSocket: websocket.WebSocket): Unit = {
    webSocket.sendTextMessage("test")
  }

  override def onFragment(s: String, b: Boolean): Unit = {}

  override def onError(throwable: Throwable): Unit = {}

  override def onClose(webSocket: websocket.WebSocket): Unit = {
    latch.countDown()
  }
}).build()).get()

val result = webSocketClient.sendTextMessage("true")
println("================================" + result)

result 变量未在控制台上打印,给出 json 解析器异常。

更新:我在 ws://0.0.0.0:9000/testSocket 中的 WebSocket 连接位于不同项目的 Scala 控制器中,如下所示:

def sockeTest = WebSocket.tryAccept[JsValue] { request =>
  futureJsonVariable.map { json =>
    val in = Iteratee.ignore[JsValue]
    // Some database computation here which generated a Future[JsValue] value in futureJsonVariable variable.
    val out = Enumerator(json).andThen(Enumerator.eof)
    Right((in, out))
  } recover {
    case err => Left(InternalServerError(err.getMessage))
  }
}

Update2:我想问的最后一件事是,我们使用 webSocket.sendMessage("test".getBytes()) 调用 WebSocket 连接,它在重写方法中给出了 WebSocket 的响应onMessage()。我想知道,我们如何等待直到收到 WebSocket 响应,以便我们可以使用 WebSocket 响应数据执行所需的计算。我已经通过在 onMessage() 方法中返回一个 Future[JsValue] 变量进行了检查,但是那个东西是无效的。那么我们如何将 webSocket.sendMessage("test".getBytes()) 置于等待模式,以便在 WebSocket 响应时执行进一步的代码?

Play 不支持 WebSocket 客户端连接。最好的选择可能是使用 AsyncHttpClient,这是构建 Play 的 WS API 的库,因此它已经在您的类路径中,使用它访问 WebSockets 的说明在这里:

https://github.com/AsyncHttpClient/async-http-client