Scala Play:Concurent.broadcast不使用EventSource

时间:2015-09-23 16:44:30

标签: javascript scala playframework playframework-2.0 server-sent-events

我在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")
}

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

1 个答案:

答案 0 :(得分:1)

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

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支持生成两种类型的路由器,一种是依赖   注入路由器,另一个是静态路由器。默认是   静态路由器,但是如果您使用创建了一个新的Play应用程序   播放种子激活模板,您的项目将包括以下内容   build.sbt中的配置告诉它使用注入的路由器:

     

routesGenerator:= InjectedRoutesGenerator

     

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

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