我在Scala Play中遇到问题,无法将Conncurrent.broadcast
与EventSource()
联系起来以创建有效的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")
}
不知何故,当我连接这两部分时,消息不会被广播到浏览器。
答案 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文档中的代码示例假定您正在使用 注入的路由生成器。如果你不使用它,你可以 平凡地调整静态路由生成器的代码示例, 或者通过为路由的控制器调用部分添加前缀 @符号,或将每个控制器声明为对象 而不是一个班级。
我仍然不太理解最后一句,因为控制器似乎没有使用注入的路由生成器,因此@
应该使用静态路由器