Scala Play:并发.broadcast不能与EventSource一起工作



我在Scala Play中将Conncurrent.broadcastEventSource()连接以创建工作SSE聊天时遇到麻烦。

下面的代码不能工作。当用户连接到feed时,我所看到的只是调试消息,仅此而已。没有数据被发送到浏览器。我确信数据被成功地发送到服务器并推送到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部分也是可以的。

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

From play doc:

Play支持生成两种类型的路由器,一种是依赖注入型路由器,另一种是静态路由器。默认值是静态路由器,但如果您使用播放种子激活器模板,您的项目将包括以下内容构建中的配置。SBT告诉它使用注入的路由器:

routesGenerator:= InjectedRoutesGenerator

Play文档中的代码示例假设您正在使用注入的路由生成器。如果你没有使用这个,你可以简单地调整静态路由生成器的代码示例,可以在路由的控制器调用部分的前缀中加上一个@符号,或者通过将每个控制器声明为对象而不是一个类

我仍然不太理解最后一句话,因为控制器似乎不使用注入的路由生成器,因此有一个@应该使用静态路由器

最新更新