Scala Play:Concurent.broadcast 无法使用 EventSource

Scala Play: Concurent.broadcast not working with EventSource

我在 Scala Play 中遇到问题,无法将 Conncurrent.broadcastEventSource() 连接以创建有效的 SSE 聊天。

下面的代码无效。当用户连接到提要时,我所看到的只是调试消息,仅此而已。没有数据被发送到浏览器。 而且我确定数据已成功发送到服务器并推送到 chatChannel。怎么了?我该如何调试呢?

val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]

def postMessage = Action(parse.json) { req =>
  chatChannel.push(req.body)
  Ok
}

def chatFeed = Action { req =>
  println("User connected to chat: " + req.remoteAddress)
  Ok.chunked(chatOut
    &> EventSource()
  ).as("text/event-stream")
}

下面这个简单的调试代码正在运行,我在控制台中看到浏览器通过 chatChannel 发送的数据,所以这边工作正常。

val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]
val chatDebug = Iteratee.foreach[JsValue](m => println("Debug: " + m.toString))
chatOut |>>> chatDebug

def postMessage = Action(parse.json) { req =>
  chatChannel.push(req.body)
  Ok
}

这也有效,我看到随机字符串被发送到浏览器。所以JS部分也OK。

def chatFeed = Action { req =>
  val producer = Enumerator.generateM[String](Promise.timeout(Some(Random.nextString(5)),3 second))
  Ok.chunked(producer &> EventSource()).as("text/event-stream")
}

不知何故,当我连接这两个部分时,消息不会广播到浏览器。

哇!我准备放弃了,但我找到了问题的根源。

routes 文件中,您使用依赖注入路由器:

GET        /                    @controllers.Application.index
POST       /message             @controllers.Application.postMessage
GET        /feed                @controllers.Application.chatFeed

使用静态路由器(没有 @ 和默认路由器)适用于您的示例:

GET        /                    @controllers.Application.index
POST       /message             controllers.Application.postMessage
GET        /feed                controllers.Application.chatFeed

来自play doc

Play supports generating two types of routers, one is a dependency injected router, the other is a static router. The default is the static router, but if you created a new Play application using the Play seed Activator templates, your project will include the following configuration in build.sbt telling it to use the injected router:

routesGenerator := InjectedRoutesGenerator

The code samples in Play’s documentation assumes that you are using the injected routes generator. If you are not using this, you can trivially adapt the code samples for the static routes generator, either by prefixing the controller invocation part of the route with an @ symbol, or by declaring each of your controllers as an object rather than a class.

我还是不太明白最后一句话,因为控制器似乎没有使用注入路由生成器,因此 @ 应该使用静态路由器